3.2.8 dispatch_sync
dispatch_async 函数的“async”意味着 “非同步”(asynchronous)就是将指定的Block”非同步”地追加到指定的Dispatch Queue中,dispatch_async函数不做任何等待。

既然有“async”当然也就有“sync”,即 dispatch_sync函数。它意味着“同步”(synchronous)也就是将指定的Block”同步”追加到指定的Dispatch Queue中。在追加Block结束之前,dispatch_sync函数会一直等待。
Dispatch_sync函数的处理流程
如 dispatch_group_wait函数中的说明,“等待”意味着当前线程停止。
- 我们先假设这样一种情况:执行Main Dispatch Queue 时,使用另外的线程Global Dispatch Queue进行处理,处理结束后立即使用所得到的结果。在这种情况下就要使用dispatch_sync函数。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_sync(queue, ^{
NSLog(@"同步执行");
});
-
一旦调用dispatch_sync函数,那么在指定的处理执行结束之前,改函数不会返回。dispatch_sync函数可以简化源代码,也可以说是简易版的dispatch_group_wait函数。
-
正因为dispatch_sync函数使用简单,所以也容易引起问题,即死锁
例如 如果在主线程中执行以下源代码就会死锁。
//在Main Dispatch Queue 即主线程中执行指定的Block,并等待期执行结束。而其实在主线程中正在执行这些代码。所以无法将Block追加到Main Dispatch Queue中,导致死锁。
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"Hello?");
});
- 在Main Dispatch Queue 即主线程中执行指定的Block,并等待期执行结束。而其实在主线程中正在执行这些代码。所以无法将Block追加到Main Dispatch Queue中,导致死锁。
//Main Dispatch Queue 中执行的Blcok等待 Main Dispatch Queue 中要执行的Block执行结束。这样的思索就像是在画像上画画一样。
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"hello?");
});
});
-
Main Dispatch Queue 中执行的Blcok等待 Main Dispatch Queue 中要执行的Block执行结束。这样的思索就像是在画像上画画一样。
-
当然Serial Dispatch Queue 也会因此相同的问题。
//因为 queue2为串行队列 ,执行同步操作,那么需要等待其当前任务执行完毕,
//串行队列异步任务—>嵌套同步任务—>导致当前线程死锁.
//因为CPU执行到53行时,因为是同步任务,需要等待当前线程(目前是子线程)任务执行完,也即是51行外层嵌套的子线程的异步任务.由于外层嵌套的子线程异步任务执行时又要等待53行的同步任务执行完,所以导致相互等待,死锁.
//https://www.jianshu.com/p/c5ee8ba01993
dispatch_queue_t queue2 = dispatch_queue_create("com.examle.gcd.MySerialDispatchQueue", NULL);
dispatch_async(queue2, ^{
NSLog(@"%@",[NSThread currentThread]);
dispatch_sync(queue2, ^{
NSLog(@"Hello?");
});
});
- 另外,由 dispatch_barrier_async 函数中含有async可推测出,相应的也有dispatch_barrier_sync函数。dispatch_barrier_async函数的作用是在等待追加的处理全部执行结束后,再追加处理到Dispatch Queue 中,此外,它还与dispatch_sync函数相同,会等待追加的处理执行结束。
参考博文:
GCD死锁情况
网友评论