@SanMao
2015-08-06T11:31:45.000000Z
字数 4365
阅读 2163
多线程
纯C语言,提供了非常多强大的函数
GCD的优势
GCD中有2个核心概念
任务:执行什么操作队列:用来存放任务GCD的使用就2个步骤
将任务添加到队列中
GCD中有2个用来执行任务的常用函数
同步:只能在当前线程中执行任务,不具备开启新线程的能力
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);// queue:队列// block:任务
异步:可以在新的线程中执行任务,具备开启新线程的能力
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
并发:可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)并发功能只有在异步(dispatch_async)函数下才有效
并发队列创建
dispatch_queue_t queue = dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);// 两个参数分别是:队列的名称,队列的类型
获取全局并发队列
// GCD默认已经提供了全局的并发队列,供整个应用使用,可以无需手动创建dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);// 第一个参数是优先级,传0即可,第二参数暂时无用,传0
全局并发队列的优先级
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中)#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台
串行:让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
dispatch_queue_t queue = dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);// 两个参数分别是:队列的名称,队列的类型// 创建串行队列(队列类型传递NULL或者DISPATCH_QUEUE_SERIAL)
主队列:主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行
dispatch_queue_t queue = dispatch_get_main_queue();
* 注意:使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列
/*同步 + 主队列 = 需要记住的就一点: 同步函数不能搭配主队列使用注意: 如果是在子线程中调用同步函数 + 主对列 是可以执行的*/- (void)syncMian{// 主队列, 只要将任务放到主队列中, 那么任务就会在主线程中执行dispatch_queue_t queue = dispatch_get_main_queue();// 需要记住的就一点: 同步函数不能搭配主队列使用dispatch_sync(queue, ^{NSLog(@"1 - %@", [NSThread currentThread]);});dispatch_sync(queue, ^{NSLog(@"2 - %@", [NSThread currentThread]);});dispatch_sync(queue, ^{NSLog(@"3 - %@", [NSThread currentThread]);});NSLog(@"++++++++++++++");}/*异步 + 主队列 = 不会开启新的线程*/- (void)asyncMain{// 主队列, 只要将任务放到主队列中, 那么任务就会在主线程中执行dispatch_queue_t queue = dispatch_get_main_queue();// 如果任务放在主队列中, 哪怕是异步方法也不会创建新的线程dispatch_async(queue, ^{NSLog(@"1 - %@", [NSThread currentThread]);});dispatch_async(queue, ^{NSLog(@"2 - %@", [NSThread currentThread]);});dispatch_async(queue, ^{NSLog(@"3 - %@", [NSThread currentThread]);});}/*同步 + 串行 = 不会创建新的线程注意: 如果是同步函数, 只要代码执行到了同步函数的那一行, 就会立即执行任务, 只有任务执行完毕才会继续往后执行*/- (void)syncSerial{// 1.创建队列/*正是因为线程默认就是串行, 所以创建串行队列的时候, 队列类型可以不传值*/// dispatch_queue_t queue = dispatch_queue_create("com.520it.lnj", DISPATCH_QUEUE_SERIAL);dispatch_queue_t queue = dispatch_queue_create("com.520it.lnj", NULL);// 2.添加任务dispatch_sync(queue, ^{NSLog(@"1 - %@", [NSThread currentThread]);});dispatch_sync(queue, ^{NSLog(@"2 - %@", [NSThread currentThread]);});dispatch_sync(queue, ^{NSLog(@"3 - %@", [NSThread currentThread]);});NSLog(@"%s", __func__);}/*同步 + 并行 = 不会开启新的线程注意: 能不能开启新的线程, 和并行/串行没有关系, 只要函数是同步还是异步*/- (void)syncConcurrent{// 1.创建队列dispatch_queue_t queue = dispatch_get_global_queue(0, 0);// 2.添加任务dispatch_sync(queue, ^{NSLog(@"1 - %@", [NSThread currentThread]);});dispatch_sync(queue, ^{NSLog(@"2 - %@", [NSThread currentThread]);});dispatch_sync(queue, ^{NSLog(@"3 - %@", [NSThread currentThread]);});NSLog(@"%s", __func__);}/*异步 + 串行 = 会创建新的线程, 但是只会创建一个新的线程, 所有的任务都在这一个新的线程中执行异步任务, 会先执行完所有的代码, 再在子线程中执行任务*/- (void)asyncSerial{// 1.创建队列dispatch_queue_t queue = dispatch_queue_create("com.520it.lnj", DISPATCH_QUEUE_SERIAL);// 2.添加任务dispatch_async(queue, ^{NSLog(@"1 - %@", [NSThread currentThread]);});dispatch_async(queue, ^{NSLog(@"2 - %@", [NSThread currentThread]);});dispatch_async(queue, ^{NSLog(@"3 - %@", [NSThread currentThread]);});NSLog(@"%s", __func__);}/*异步 + 并行 = 会开启新的线程*/- (void)asynConcurrent{/*第一个参数: 队列第二个参数: 任务*/// 1.创建队列/*第一个参数: 队列的名称第二个参数: 队列的类型*/// dispatch_queue_t queue = dispatch_queue_create("com.520it.lnj", DISPATCH_QUEUE_CONCURRENT);// 其实系统内部已经给我们提供了一个现成的并发队列/*第一个参数: iOS8以前是线程的优先级/ iOS8以后代表服务质量iOS8以前* - DISPATCH_QUEUE_PRIORITY_HIGH: 2* - DISPATCH_QUEUE_PRIORITY_DEFAULT: 0* - DISPATCH_QUEUE_PRIORITY_LOW: -2* - DISPATCH_QUEUE_PRIORITY_BACKGROUND: -32768iOS8开始, 取值都是十六进制* - QOS_CLASS_USER_INTERACTIVE 用户交互(用户迫切的想执行任务, 不要在这种服务质量下做耗时的操作)* - QOS_CLASS_USER_INITIATED 用户需要* - QOS_CLASS_DEFAULT 默认(重置队列)* - QOS_CLASS_UTILITY 实用工具(耗时的操作放在这里)* - QOS_CLASS_BACKGROUND* - QOS_CLASS_UNSPECIFIED 没有设置任何优先级第二个参数: 系统保留的参数, 永远传0*/// 1.获取全局的并发队列dispatch_queue_t queue = dispatch_get_global_queue(0 , 0);// 2.添加任务到队列// 文档说明是FIFO原则, 先进先出// 打印结果不正确的原因: 线程的执行速度可能不一样, 有得快一些, 有的慢一些dispatch_async(queue, ^{NSLog(@"1 - %@", [NSThread currentThread]);});dispatch_async(queue, ^{NSLog(@"2 - %@", [NSThread currentThread]);});dispatch_async(queue, ^{NSLog(@"3 - %@", [NSThread currentThread]);});NSLog(@"%s", __func__);}