dispatch_async,异步任务
dispatch_sync,同步任务
1.异步任务会开启新线程,并行队列线程数不确定,执行完的线程回收前可以被其他任务复用(类似cell重用)。
2.dispatch_get_global_queue(identifier, flags),全局队列
参数flags:iOS预留参数,填0即可。
参数identifier:
Ios7,优先级。
#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 //后台执行,最慢,CPU切换到的频率很低
Ios8,服务质量。
QOS_CLASS_USER_INTERACTIVE //用户交互,希望线程被快速执行,不要做耗时操作
QOS_CLASS_USER_INITIATED //用户需要的,同样不要使用耗时操作
QOS_CLASS_DEFAULT //默认,系统用来重置队列。
QOS_CLASS_UTILITY //使用工具,用来做耗时操作
QOS_CLASS_BACKGROUND //后台执行,线程执行非常慢
QOS_CLASS_UNSPECIFIED //没有优先级,值为0,可以兼容ios7。
3.并发队列:效率高,消耗大,可以同时调度多个任务。
串行队列:效率低,消耗小,一个任务执行完再调度下一个任务。
全局队列:一个特殊的并发队列,由系统默认创建。
主队列:一个任务执行完再调度下一个任务,不会开启新线程,即使异步任务也会顺序执行,和串行队列类似但有区别。不能在主队列使用同步任务,会造成死锁。
NSLog(@"任务1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"任务2");
});
NSLog(@"任务3");
"这里我的理解是:类似优先级反转,任务3在任务2未完成时添加到队列,就会先执行任务3,而由于是依次执行,任务2未完成并返回,
任务3不能执行,此时任务3未完成,任务2也不能执行"
问:主队列只有一条线程运行,同步和异步有什么区别?异步为什么不死锁?
4.延时执行,异步执行。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(sec * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{ });
参数1:时间,dispatch_time(DISPATCH_TIME_NOW, (int64_t)(sec * NSEC_PER_SEC)
DISPATCH_TIME_NOW:从当前时间开始计算经过多少纳秒后执行。
NSEC_PER_SEC:1秒等于多少纳秒。
参数2:队列。
参数3:任务block。
5.在app生命周期内只执行一次,线程安全,比互斥锁效率高。onceToken必须使用全局的,否则在多线程中不安全。
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ });
6.dispatch_group_t,调度组,在多个任务都完成后再执行某个任务。
dispatch_group_t group = dispatch_group_create();
"新任务开始,每一个任务开始必须匹配一个结束,不然notify一直等待。"
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"任务1");
dispatch_group_leave(group);//新任务结束
});
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"任务2");
dispatch_group_leave(group);
});
"所有通过同一个group开启的任务都结束后再执行的任务。"
dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"任务3");
});
"等待任务1和任务2都完成再往下执行,不用等待任务3"
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"123");
7.栅栏函数。
dispatch_barrier_async,分割队列中的异步任务,栅栏之前的所有异步任务执行完后再执行栅栏之后的异步任务。
dispatch_barrier_sync,分割所有任务(包括主队列中的任务),不能直接在主队列使用会造成死锁。
问:在dispatch_get_global_queue(0, 0)中两个函数都不起作用,why???
dispatch_queue_t q = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(q, ^{
sleep(2);
NSLog(@"任务1");
});
NSLog(@"任务2");
dispatch_barrier_async(q, ^{
sleep(1);
NSLog(@"barrier");
});
NSLog(@"任务3");
dispatch_async(q, ^{
NSLog(@"任务4");
});
8.dispatch_apply。
循环执行某个任务,如果是并发队列异步执行,串行队列同步执行。函数本身为同步函数,要防死锁,不能在主队列执行。
! dispatch_apply函数说明
*
* @brief dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API
* 该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,并等到全部的处理执行结束
*
* @param 10 指定重复次数 指定10次
* @param queue 追加对象的Dispatch Queue
* @param index 带有参数的Block, index的作用是为了按执行的顺序区分各个Block
*
*/
9.dispatch_semaphore_create & dispatch_semaphore_signal & dispatch_semaphore_wait
"创建信号量,并设置信号量数量,即最大并发数。
dispatch_semaphore_t t = dispatch_semaphore_create(0);
第二个参数 timeOut:超时时间,超时直接信号量+1,任务依然会执行完毕。类型为dispatch_time_t,系统定义
DISPATCH_TIME_NOW 表示当前
DISPATCH_TIME_FOREVER 表示遥远的未来
也可以通过 dispatch_time 和 dispatch_walltime 来自定义时间。"
dispatch_queue_t q = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_time_t duration = dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC);
"超时10秒,设置后如果此处信号量为0则在此处等待10秒后再往下执行,注意设置超时必须是在此处信号量(-1之前)为0时才能生效。
wait使信号量-1,信号量为0时后面的任务(即下一个wait之后的所有任务)进入等待状态,只有获取到信号量或者等待超时才能继续执行。"
dispatch_semaphore_wait(t, duration);
dispatch_async(q, ^{
sleep(1);
NSLog(@"任务1");
"信号量+1"
dispatch_semaphore_signal(t);
});
NSLog(@"任务2");
"此时等待任务4也不会执行,即等待的是后面包括主线在内的所有任务,需要任务1释放信号量后再执行后面任务"
dispatch_semaphore_wait(t, DISPATCH_TIME_FOREVER);
dispatch_async(q, ^{
sleep(2);
NSLog(@"任务3");
dispatch_semaphore_signal(t);
});
NSLog(@"任务4");
dispatch_semaphore_wait(t, DISPATCH_TIME_FOREVER);
dispatch_async(q, ^{
sleep(1);
NSLog(@"任务5");
dispatch_semaphore_signal(t);
});
NSLog(@"任务6");
执行顺序:
2018-07-09 15:22:36.152 ios_GCD[1341:508652] 任务2
2018-07-09 15:22:47.157 ios_GCD[1341:508707] 任务1
2018-07-09 15:22:47.158 ios_GCD[1341:508652] 任务4
2018-07-09 15:22:49.164 ios_GCD[1341:508707] 任务3
2018-07-09 15:22:49.164 ios_GCD[1341:508652] 任务6
2018-07-09 15:22:50.173 ios_GCD[1341:508707] 任务5