@SanMao
2015-08-06T19:31:45.000000Z
字数 4365
阅读 1964
多线程
纯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: -32768
iOS8开始, 取值都是十六进制
* - 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__);
}