- (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
待補充
待補充