1. 死锁
所谓死锁
,通常指有两个线程A和B都卡住了无法完成,都在等待对方完成任务
后在执行。A不能完成是因为它在等待B完成。但B也不能完成,因为它在等待A完成
。于是大家都无法完成任务,就导致了死锁(DeadLock)。
2 同步/异步函数
同步,异步区别
- 能否开辟
新线程
- 任务回调是否具备
异步性 - 同步性
死锁
情况的产生
2.1 同步函数
下面分析串行和并行执行同步函数的情况。
串行
上文说到同步函数实现会走到这里,这里看到dq_width == 1
的时候,也就是当是串行队列的时候,会调用_dispatch_barrier_sync_f
。
搜索_dispatch_barrier_sync_f。发现调用了_dispatch_barrier_sync_f_inline
。
搜索_dispatch_barrier_sync_f_inline。
当死锁的时候,都会调用_dispatch_sync_f_slow
,所以这里需要看_dispatch_sync_f_slow。这里也可以知道_dispatch_sync_f_slow不报错,报错的是 __DISPATCH_WAIT_FOR_QUEUE__
进去_dispatch_sync_f_slow。
接下来看报错的地方,也就是__DISPATCH_WAIT_FOR_QUEUE__
,看到其报错的地方有条件判断,那么就进去看是如何判断是死锁的。这里的2个参数一个是线程状态,一个是线程id。
这里做了中间层封装,实际调用_dispatch_lock_is_locked_by
。
点进去_dispatch_lock_is_locked_by。DLOCK_OWNER_MASK
是个很大的值,只要(lock_value ^ tid) 不为空
,那么与上DLOCK_OWNER_MASK就不会为0
。如果(lock_value ^ tid) & DLOCK_OWNER_MASK为0
,那么就代表着(lock_value ^ tid)为0
,那么就说明lock_value等于tid
。那么就说明,本来是要调起这个队列,但是这个队列原定是要等待的,构成了一个矛盾,所以发生了死锁
。