dispatch_sync()死锁

关于死锁,觉得一直理解的不够充分,或者说理解的有些牵强,最近还是决定查些资料,把问题和理解记录下来。

串行队列:

        任务按照顺序添加在一个队列中,依次执行,常用的串行队列有主队列main queue和一般的串行队列serial queue;

dispatch_sync():

        同步任务,即前一个任务执行完毕,后面的任务才会开始执行,否则后面的任务都处于等待状态;

死锁发生的原因:

        如果在同一个串行队列中,强调一下,必须是同一个串行队列,如果主队列中的有个执行函数未执行完毕,恰好执行函数中通过dispatch_sync()添加同步任务,这时就会发生死锁;说的详细点就是,主队列中的执行函数当前是作为第一个任务正在执行,必须执行完该函数,才算执行完首个任务并返回结果,此时才会向下执行后面的任务,如果此时执行函数中又通过dispatch_sync()同步添加了任务(newTask),那么执行函数必须等新任务newTask执行完,才能向下执行,才算执行函数调用结束,即首个任务执行完毕,而newTask作为同步添加的第二个任务,又在等首个任务即执行函数执行完,才会开始执行,这样就出现了相互等待的情况,两个任务永远无法执行完,即出现死锁。

下面介绍常遇到的几个场景:

场景1:

viewDidLoad是执行函数,它永远无法执行完毕,始终在等待添加的同步任务dispatch_sync;而同步任务一直在等viewDidLoad执行完才能执行,就造成死锁。

场景2:

队列queue1中的任务通过dispatch_async开辟了一个子线程执行,queue2虽然是作为一个并发队列,但是因为是同步的,所以并不会开辟新的线程,会在当前线程中执行, dispatch_sync(queue2, ...)的任务是在另一个队列queue2中执行的,没有相互等待的现象,不会死锁。

场景3:

同样的情况,dispatch_async(queue,...)开辟了一个新的异步子线程执行任务,第一个任务打印出来是在queue中执行的,dispatch_sync(dispatch_get_main_queue(),...)添加的同步任务会回到主队列中执行的,回到主线程中;因此,因为在两个队列中执行,也不会出现相互等待的现象,就不会出现死锁。

总结
1. 队列中排队的任务,最终会通过线程调度执行。
2. dispatch_sync() 是线程同步操作,其作用就是阻塞当前线程,先让dispatch_sync()的block执行完毕,才会返回, 后面的任务才会接着执行。
3. dispatch_sync() 造成死锁的条件是:如果在同一个队列(主队列或其他串行队列)添加同步任务,会出现任务相互等待,就会死锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值