最近在使用信号量时,遇到了一种死锁的情况。
//在主线程写一段代码,并运行
NSLog(@"1");
dispatch_semaphore_t s = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"2");
dispatch_semaphore_signal(s);
});
});
NSLog(@"3");
dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER);
NSLog(@"4");
2018-02-09 11:27:28.603660+0800 test[10630:7608773] 1
2018-02-09 11:27:28.603941+0800 test[10630:7608773] 3
分析:
1.创建的总信号量为0,代码执行到dispatch_semaphore_wait时, 主线程阻塞,直到收到信号才会往下继续执行;
dispatch_semaphore_signal(s)发送信号是放在主线程中执行,由于此时主线程是阻塞的,那么dispatch_semaphore_signal(s)不会执行,这形成了死锁的情况。
修改一下代码如下,运行
NSLog(@"1");
dispatch_semaphore_t s = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_signal(s);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"2");
});
});
NSLog(@"3");
dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER);
NSLog(@"4");
2018-02-22 14:44:45.589003+0800 test[631:151335] 1
2018-02-22 14:44:45.589064+0800 test[631:151335] 3
2018-02-22 14:44:45.589112+0800 test[631:151335] 4
2018-02-22 14:44:45.647069+0800 test[631:151335] 2
dispatch_semaphore_signal(s)发送信号放在子线程执行,打破了死锁,代码正常执行了。