- (void)wbinterDemo{
dispatch_queue_t queue = dispatch_queue_create("com.demo.test", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"1");
});
dispatch_async(queue, ^{
NSLog(@"2");
});
dispatch_sync(queue, ^{ NSLog(@"3"); });
NSLog(@"0");
dispatch_async(queue, ^{
NSLog(@"7");
});
dispatch_async(queue, ^{
NSLog(@"8");
});
dispatch_async(queue, ^{
NSLog(@"9");
});
// A: 1230789
// B: 1237890
// C: 3120798
// D: 2137890
}
复制代码
上面的代码打印顺序是选择A
由于串行队列至关于把异步变成同步按顺序执行 dqf_width = 1
保证FIFO
异步函数串行队列:开启一条新线程 任务一个接着一个markdown
- (void)wbinterDemo{
dispatch_queue_t queue = dispatch_queue_create("com.demo.test", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"1");
});
dispatch_async(queue, ^{
NSLog(@"2");
});
dispatch_sync(queue, ^{ NSLog(@"3"); });
NSLog(@"0");
dispatch_async(queue, ^{
NSLog(@"7");
});
dispatch_async(queue, ^{
NSLog(@"8");
});
dispatch_async(queue, ^{
NSLog(@"9");
});
// A: 1230789
// B: 1237890
// C: 3120798
// D: 2137890
}
复制代码
若是把串行改成并行的话答案选择AC
由于同步阻塞3
确定在0
以前 123
无序 789
无序 异步函数并发队列:开启线程,在当前线程执行任务 任务异步执行,没有顺序,CPU
调度有关并发
主队列与全局队列app
死锁现象异步
同步函数和异步函数的区别async
可否开辟线程函数
任务的回调是否具有异步性-同步性oop
同步串行死锁底层源码分析atom
查找dispatch_syn
查找
_dispatch_sync_f
查找
_dispatch_sync_f_inline
spa
先看一下_dispatch_barrier_sync_f
查找_dispatch_barrier_sync_f_inline
咱们运行一个demo 发现死锁
死锁最后执行的堆栈先是
_dispatch_sync_f_slow
最后执行的是 __DISPATCH_WAIT_FOR_QUEUE__
因此分析刚刚查看的_dispatch_barrier_sync_f_inline
应该走的是 _dispatch_sync_f_slow
查找一下
而后查找 __DISPATCH_WAIT_FOR_QUEUE__
看着里面的日志 和咱们 崩溃的死锁最后执行__DISPATCH_WAIT_FOR_QUEUE__
的截图日志是同样的 意味着死锁就在这里 你调用的队列被当前线程持有
咱们先查看一下 dsc->dsc_waiter
咱们查看一下 _dispatch_tid_self()
是tid
咱们查看一下 _dq_state_drain_locked_by
咱们查看一下 _dispatch_lock_is_locked_by
lock_value ^ tid = 0 & DLOCK_OWNER_MASK
才等于0
lock_value = tid
才等于0
dq_state
和 dsc->dsc_waiter
表明这两个值相同才发生死锁 这就是死锁的探究流程
同步全局队列并发底层源码分析
咱们先看一个细节
_dispatch_sync_invoke_and_complete
这个方法传参以func
开头的这个为何这么写
看一下 DISPATCH_TRACE_ARG
把逗号封装到这里 可选
并发到底走的是 _dispatch_sync_f_slow
仍是 _dispatch_sync_recurse
接下来咱们用个demo设置这两个系统断点看怎么走的
运行看结果 而后又走到
_dispatch_sync_function_invoke
而后走
_dispatch_sync_function_invoke_inline
而后
_dispatch_client_callout
回调
同步并发队列是这么走的流程
可否开辟线程
函数的异步性
异步并发
查找dispatch_async
进入 _dispatch_continuation_async
进入 dx_push
进入
dq_push
进入
_dispatch_lane_concurrent_push
进入_dispatch_lane_push
进入
dx_wakeup
进入
dq_wakeup
进入
_dispatch_lane_wakeup
进入 _dispatch_lane_barrier_complete
进入 _dispatch_lane_class_barrier_complete
os_atomic_rmw_loop2o
递归执行完会进入 _dispatch_root_queue_push
进入
_dispatch_root_queue_push_inline
进入 _dispatch_root_queue_poke
进入
_dispatch_root_queue_poke_slow
待补充
待补充