什么是死锁
死锁(deadlock) 通常是当多个线程在相互等待着对方的结束时,就会发生死锁,这时程序可能会被卡住。此时就导致了deadlock!
串行与并行
在使用GCD的时候,我们会把需要处理的任务放到Block中,然后将任务追加到相应的队列里面,这个队列,叫做Dispatch Queue。然而,存在于两种Dispatch Queue,一种是要等待上一个执行完,再执行下一个的Serial Dispatch Queue,这叫做串行队列;另一种,则是不需要上一个执行完,就能执行下一个的Concurrent Dispatch Queue,叫做并行队列。这两种,均遵循FIFO原则。
dispatch_get_global_queue
为全局并行队列
dispatch_get_main_queue
为主线程串行队列
自己也可以创建队列:
//创建串行队列dispatch_queue_create("com.demo.serialQueue", DISPATCH_QUEUE_SERIAL)
//创建并行队列dispatch_queue_create("com.demo.concurrentQueue", DISPATCH_QUEUE_CONCURRENT)
同步和异步
首先同步异步是对于线程来说的,主要区别是是否等待IO操作(并不一定是)执行完成,即是否阻塞当前线程,其中的 IO 操作肯定是别的线程去执行的
并发执行的多个任务中可能存在多个线程,其中的多个线程有可能是同步执行的 也有可能是异步执行的
//同步线程dispatch_sync(某个队列信息,^(block))
//异步线程dispatch_async(某个队列信息,^(block))
让我们来解锁吧
当前串行队列里面同步执行当前串行队列就会死锁,解决的方法就是将同步的串行队列放到另外一个线程就能够解决。
1 | NSLog(@"1"); |
这里的死锁不是因为在主线程执行,而是在main_queue内部的两个任务:dispatch_sync和NSLog相互等待导致。NSLog(@”2”)要等dispatch_sync执行完,而在执行NSLog(@”2”)执行完以前,dispatch_sync又不会结束。
实际上,这里在主线程运行(串行线程),在主线程(当前串行队列)同步执行打印2时会产生互相等待而死锁。
1 | NSLog(@"1"); |
这里不死锁,同步任务在全局并行队列中,因此2执行完就跳转到主线程执行3。
1 | dispatch_queue_t serialQueue = dispatch_queue_create("com.starming.gcddemo.serialqueue", DISPATCH_QUEUE_SERIAL); |
1 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ |
以上部分欢迎讨论
参考资料
并发编程
Effective Objective-C Notes:GCD 实现同步锁
细说GCD(Grand Central Dispatch)如何用