多线程的几种方式

在iOS开发中有四种多线程的写法
1.Pthread
(这是一套通用的多线程API,但是现在几乎很少人用了);
2.NSThread
(可以直接操作的分线程,偶尔使用);
3.GCD
(苹果官方推出的替代NSThread的一种写法,利用设备的多核性能,经常被使用);
4.NSOperation
(面向对象的,GCD上的OC接口,经常被使用);

pthread的用法
1.创建线程
{    pthread_t thread ;
     int error = pthread_create(&thread, NULL, task, NULL);
     if (error != 0) {
        NSLog(@"创建pthread类型的子线程失败");
      }
}

/*
int  pthread_create(pthread_t  *  thread,
pthread_attr_t * attr,
void * (*start_routine)(void *),
void * arg)
thread:返回创建的线程的ID
attr:线程属性,调度策略、优先级等都在这里设置,如果为NULL则表示用默认属性
start_routine:线程入口函数,可以返回一个void*类型的返回值,该返回值可由pthread_join()捕获
arg:传给start_routine的参数, 可以为NULL
*/

void *task(void *data){
    for (int i=0; i<300000; i++) {
        NSLog(@"当前运行次数%d",i);
    }
    return 0;
}

pthread_create();//创建一个线程
pthread_exit();//终止当前线程
pthread_cancel();//中断另外一个线程的运行
pthread_join();//阻塞当前的线程,直到另外一个线程运行结束
pthread_attr_init();//初始化线程的属性
pthread_attr_setdetachstate();//设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
pthread_attr_getdetachstate();//获取脱离状态的属性
pthread_attr_destroy();//删除线程的属性
pthread_kill();//向线程发送一个信号
NSThread用法
//先设计一个耗时操作
-(void)longtime task{
//在耗时操作里面打印当前线程对象
    NSThread *currentThread = [NSThread currentThread];
    NSLog(@"%@",currentThread);
    for (int i=0; i<300000; i++) {
        NSLog(@"当前运行次数%d",i);
    }
}
//在程序中随意一个地方调起耗时操作(使用NSThread的方式调起)
//方式1:
[self performSelectorInBackground:@selector(longtimetask) withObject:nil];//iOS9以后,苹果公司觉得这个开线程的方法不安全,不推荐使用
//方式2:使用NSThread类方法创建多线程
    [NSThread detachNewThreadSelector:@selector(longtimetask) toTarget:self withObject:nil];

//以上方式1和2 写法都是自动创建线程并且自动启动,但是无法设置线程的一些属性:例如线程的名字,线程的优先级

//方式3:使用NSThread创建线程对象,并给予对象的属性赋值
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(longtimetask) object:nil];
    thread.name = @"子线程";//设置线程的名字
    thread.threadPriority = 0.5;//设置线程的优先级(0.0 - 1.0,1.0最高级,最高级的子线程会被系统优先执行 )iOS8以后,使用了枚举类型的优先级qualityOfService;以下是从高到低排列
    thread.qualityOfService = NSQualityOfServiceUserInteractive;//和视图相关的(优先级最高)
    thread.qualityOfService = NSQualityOfServiceUserInitiated;//用户使用某个功能
    thread.qualityOfService = NSQualityOfServiceUtility;//周期性操作,例如每五分钟循环请求网络数据;
    thread.qualityOfService = NSQualityOfServiceBackground;//用户察觉不到的,做成功或者失败用户都没有感觉出来的事件
    thread.qualityOfService = NSQualityOfServiceDefault;//这个优先级是最低的
    [thread start];//启动线程

//如何退出子线程?
//在子线程的执行事件中找到自己想要的时机执行下面这句代码:
[NSThread exit];

//备注:不要在子线程中执行视图视图事件
//例如图片视图想要显示网络中的图片,下载图片的方法可以写在子线程中,但是显示图片的方法,就要回到主线程中操作
//NSThread 方式回到主线程的方法是:
[self performSelectorOnMainThread:@selector(refreshImageview:) withObject:downloadimage waitUntilDone:YES];
//waitUntilDone:(BOOL)wait 的意义是:YES表示回到主线程后,主线程所有的事件执行完毕才会再接着执行子线程上的剩余任务,NO表示主线程的事件和子线程的事件不相干扰,同步执行.
//如果需要重复启动一个线程,那么再启动线程之前需要先判断这个线程是否已经结束
if (self.thread.isFinished || self.thread.executing) {
        self.thread = nil;
    }


//线程锁(限制一个方法同一时间内只能被一个线程所运行)
1.声明一个线程锁属性;
NSLock *lock ;//然后对这个线程锁进行初始化
2.在被线程调用的方法内部加上加锁和解锁的代码
[self.lock lock];//加锁
[self.lock unlock];//解锁

3.GCD的使用
GCD的使用主要分为:a:主线程串行 b:主线程并行 c:子线程串行 d:子线程并行

a.主线程串行的情况

//使用GCD进行线程管理的必须创建任务队列
dispatch_queue_t queue1 = dispatch_queue_create("同步串行", DISPATCH_QUEUE_SERIAL);
//其中参数1.官方描述是一个添加到队列的字符串,可以为空,具体作用不知
//参数2.的作用是用来标记任务队列是串行还是并行.(DISPATCH_QUEUE_SERIAL-串行, DISPATCH_QUEUE_CONCURRENT-并行)

//任务队列创建好以后,需要加入到线程中,并同时添加任务
//dispatch_sync(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>) (主线程的开启方法)
//dispatch_async(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)(子线程的开启方法)

//下面代码是在主线程中添加一个串行任务队列执行两个任务
//创建执行任务的队列
    dispatch_queue_t queue1 = dispatch_queue_create("同步串行", DISPATCH_QUEUE_SERIAL);//DISPATCH_QUEUE_CONCURRENT,DISPATCH_QUEUE_SERIAL
    //开启线程
    dispatch_sync(queue1, ^{
        
        for (int i = 0;  i<10; i++) {
            NSLog(@"i=%d,当前线程:%@",i,[NSThread currentThread]);
            [NSThread sleepForTimeInterval:1];
        }
    });
    
    dispatch_sync(queue1, ^{
        for (int j = 0;  j<10; j++) {
            NSLog(@"j=%d,当前线程:%@",j,[NSThread currentThread]);
            [NSThread sleepForTimeInterval:1];
        }
    });
//运行起来会发现,系统会先执行完任务队列中的第一个任务,然后再执行第二个任务.

b.主线程并行的情况

//事实上主线程执行的代码并不会有并行的情况,如果任务全部放在主线程执行,系统会默认按照任务的先后添加顺序一次完成.

c.子线程串行的情况

//子线程的串行和主线程串行的效果很相似,区别在于,系统默认主线程的优先级在子线程之上

//子线程的意义在于:系统会把多个任务放在同一个子线程上依照任务的添加顺序呢依次完成


d.子线程并行的情况

//创建执行任务的队列
    dispatch_queue_t queue4 = dispatch_queue_create("异步并行", DISPATCH_QUEUE_CONCURRENT);//DISPATCH_QUEUE_CONCURRENT,DISPATCH_QUEUE_SERIAL
    //开启线程
    dispatch_async(queue4, ^{
        
        for (int i = 0;  i<10; i++) {
            NSLog(@"i=%d,当前线程:%@",i,[NSThread currentThread]);
            [NSThread sleepForTimeInterval:1];
        }
    });
    
    dispatch_async(queue4, ^{
        for (int j = 0;  j<10; j++) {
            NSLog(@"j=%d,当前线程:%@",j,[NSThread currentThread]);
            [NSThread sleepForTimeInterval:1];
        }
    });

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容

  • 一.资源抢夺 2> 资源抢夺解决方案 @sychronized{ } dispatch_barrier_async...
    蓝心儿的蓝色之旅阅读 1,363评论 0 4
  • AngularJShttp://www.w3school.com.cn/js/pro_js_history.asp...
    iStig阅读 647评论 0 50
  • 从写信到微信,这么多年,你一直住在我心里。 从课桌上传递纸条开始的爱情,曾经搜肠刮肚写下情书,连连发上几个通宵的短...
    朝歌大叔阅读 602评论 4 11
  • 小外女生在海外, 周围全都是大海。 天天隔海看身外, 可知我们挂心怀?
    若无闲事阅读 368评论 0 1
  • 正向思维和负向思维打架,最终谁是赢家,这取决于我们的生活态度吧。每一天,希望都是晴朗的。
    Hi任小楠阅读 159评论 0 0