您的位置:首页 > 移动开发 > IOS开发

iOS多线程编程及GCD简介

2016-05-26 01:17 363 查看

程序APP进程、线程、多线程

1.程序是计算机(电脑,智能手机,机器人等有操作系统的智能新生物)指令的集合,以文件形式存储在磁盘上。

2.进程是一个正在运行的程序实例,是一个程序在其自身的地址空间中的一次执行活动。

3.进程由内核对象和地址空间组成。

4.线程由内核对象和线程栈组成,它是进程运行过程中的某个时间片,多核CUP时,线程就实现了同时运行。

iOS提供四种多线程编程技术

NSThread

NSThread相对其他几个比较轻量级。

需要自己管理线程的生命周期,线程同步。

线程同步对数据的加锁会有一定的系统开销。

Cocoa NSOperation

不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。

相关类NSOperation,NSOperationQueue。

NSOperation是个抽象类,使用它必须用它的子类,可以自定义子类或用Cocoa定义好的两个子类NSInvocationOperation, NSBlockOperation.

创建NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行。

pthread

pthread是一套通用的多线程API,适用于Linux、windows、Unix跨平台,可移植,使用C语言,生命周期需要程序员管理,iOS开发中使用很少。

GCD

Grand Central Dispatch是iOS4.0开始后,Apple开发的一个多核编程的解决方案。

GCD确实好用,很强大,是替代其他多线程编程很高效强大的技术。相比NSOperation无法提供取消任务的功能。用不好可能出现线程死锁。如

- (void)viewDidLoad{
[super viewDidLoad];
NSLog(@"=================4");
dispatch_sync(dispatch_get_main_queue(),^{
NSLog(@"=================5");
});
NSLog(@"=================6");
}


应改为

- (void)viewDidLoad{
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"=================1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"=================2");
});
NSLog(@"=================3");
});
}


GCD多线程的管理

开不开线程,取决于执行任务的函数,同步不开,异步才能开

开几条线程,取决于队列,串行开一条,并发可以开多条(异步)

串行队列Serial Dispatch Queue

队列中的任务只会顺序执行,主队列是系统自带的串行队列。

要避免多线程更新相同资源导致数据竞争时,用串行队列.

dispatch_queue_t q = dispatch_queue_create("nameOfQueue",dispatch_queue_serial);


并行队列Concurrent Dispatch Queue

队列中的任务通常会并发执行,全局队列是系统提供的并行队列。

dispatch_queue_t q = dispatch_queue_create("nameOfQueue",dispatch_queue_concurrent);


全局队列

是系统提供的,直接拿过来用就可以;与并行队列类似,但是调试时,无法确认操作所在队列。

dispatch_queue_t q = dispatch_global_queue_create(DISPATCH_QUEUE_PRIORITY_DAFAULT,0);


主队列

每一个应用开发程序对应唯一一个主队列,直接get即可,在多线程开发中,使用主队列更新UI。

dispatch_queue_t q = dispatch_get_main_queue(DISPATCH_QUEUE_PRIORITY_DAFAULT,0);


请吃栗子

GCD实现1,2并行和3串行和4,5串行,4,5是并行。3延时3秒执行。即3依赖,1,2执行,4,5依赖3的执行。

- (void)mutiThreadWork{
//同步执行1,2
dispatch_group_t group  = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
NSLog(@"1");
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"2");
});
//1,2处理晚后,延时执行3
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,3ull*NSEC_PER_SEC);
dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
dispatch_group_notify(group,dispatch_get_main_queue(),^{
NSLog(@"3");

//同步执行4,5
dispatch_group_t group2  = dispatch_group_create();
dispatch_group_async(group2, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"4");
});
dispatch_group_async(group2, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"5");
});
});
});
}


GCD实现信号量管理

请参阅:

http://blog.csdn.net/huifeidexin_1/article/details/9494975

http://blog.csdn.net/yongyinmg/article/details/38065255

GCD死锁

请参阅:

iOS 开发微信公众号博文

总结一句话:除非串行队列(主队列)的外层有不同队列的异步线程,否则串行队列的同步线程造成死锁。

GCD使用应该注意的

主队列是GCD自带的串行队列,会在主线程中执行。异步全局并发队列开启新线程,并发执行。

并行队列里开启同步任务是有执行顺序的,只有异步才没有顺序。 串行队列开启异步任务后嵌套同步任务造成死锁。

串行队列开启异步任务,是有顺序的。

串行队列开启异步任务后,嵌套同步任务造成死锁。

更多内容请参阅《Objective-C高级编程——iOS与OS X多线程和内存管理》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息