OC底層原理24-GCD分析中

一.課程答疑

- (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

Xnip2021-08-10_21-35-32.jpg

死鎖現象異步

  • 主線程由於你同步函數的緣由等着先執⾏任務
  • 主隊列等着主線程的任務執⾏完畢再執⾏⾃⼰的任務
  • 主隊列和主線程相互等待會形成死鎖 

二.同步函數死鎖

同步函數和異步函數的區別async

可否開闢線程函數

任務的回調是否具有異步性-同步性oop

libdispatch-1271.120.2源碼源碼分析

同步串行死鎖底層源碼分析atom

查找dispatch_syn Xnip2021-08-10_22-03-45.jpg 查找_dispatch_sync_f Xnip2021-08-10_22-07-03.jpg 查找_dispatch_sync_f_inlinespa

Xnip2021-08-10_22-08-05.jpg

先看一下_dispatch_barrier_sync_f

Xnip2021-08-10_22-11-56.jpg

查找_dispatch_barrier_sync_f_inline

Xnip2021-08-10_22-12-32.jpg

咱們運行一個demo 發現死鎖

Xnip2021-08-10_22-20-04.jpg 死鎖最後執行的堆棧先是_dispatch_sync_f_slow

Xnip2021-08-10_22-20-19.jpg

最後執行的是 __DISPATCH_WAIT_FOR_QUEUE__

Xnip2021-08-10_22-20-36.jpg

因此分析剛剛查看的_dispatch_barrier_sync_f_inline 應該走的是 _dispatch_sync_f_slow 查找一下

Xnip2021-08-10_22-24-13.jpg

而後查找 __DISPATCH_WAIT_FOR_QUEUE__

Xnip2021-08-10_22-26-16.jpg

看着裏面的日誌 和咱們 崩潰的死鎖最後執行__DISPATCH_WAIT_FOR_QUEUE__的截圖日誌是同樣的 意味着死鎖就在這裏 你調用的隊列被當前線程持有

咱們先查看一下 dsc->dsc_waiter

Xnip2021-08-10_22-34-57.jpg

咱們查看一下 _dispatch_tid_self()tid

Xnip2021-08-10_22-35-31.jpg

咱們查看一下 _dq_state_drain_locked_by

Xnip2021-08-10_22-36-45.jpg

咱們查看一下 _dispatch_lock_is_locked_by

Xnip2021-08-10_22-37-41.jpg

lock_value ^ tid = 0 & DLOCK_OWNER_MASK 纔等於0 lock_value = tid 纔等於0

Xnip2021-08-10_22-39-33.jpg dq_statedsc->dsc_waiter 表明這兩個值相同才發生死鎖 這就是死鎖的探究流程

三.同步函數任務同步

同步全局隊列併發底層源碼分析

Xnip2021-08-10_22-46-25.jpg 咱們先看一個細節_dispatch_sync_invoke_and_complete 這個方法傳參以func開頭的這個爲何這麼寫

Xnip2021-08-10_22-56-43.jpg

看一下 DISPATCH_TRACE_ARG

Xnip2021-08-10_23-02-24.jpg

把逗號封裝到這裏 可選

併發到底走的是 _dispatch_sync_f_slow 仍是 _dispatch_sync_recurse 接下來咱們用個demo設置這兩個系統斷點看怎麼走的

Xnip2021-08-10_22-48-55.jpg

運行看結果 Xnip2021-08-10_22-49-45.jpg 而後又走到 _dispatch_sync_function_invoke Xnip2021-08-10_23-10-18.jpg 而後走_dispatch_sync_function_invoke_inline Xnip2021-08-10_23-11-19.jpg 而後_dispatch_client_callout回調 Xnip2021-08-10_23-11-30.jpg

同步併發隊列是這麼走的流程 Xnip2021-08-10_23-20-06.jpg

四.異步函數分析上

可否開闢線程

函數的異步性

異步併發

查找dispatch_async

Xnip2021-08-11_16-18-46.jpg

進入 _dispatch_continuation_async

Xnip2021-08-11_17-12-04.jpg

進入 dx_push

Xnip2021-08-11_17-12-35.jpg 進入 dq_push

Xnip2021-08-11_17-18-16.jpg 進入 _dispatch_lane_concurrent_push

Xnip2021-08-11_17-19-07.jpg

進入_dispatch_lane_push

Xnip2021-08-11_17-20-18.jpg 進入 dx_wakeup

Xnip2021-08-11_17-20-41.jpg 進入 dq_wakeup

Xnip2021-08-11_17-21-52.jpg 進入 _dispatch_lane_wakeup

Xnip2021-08-11_17-22-22.jpg

進入 _dispatch_lane_barrier_complete

Xnip2021-08-11_17-24-38.jpg

進入 _dispatch_lane_class_barrier_complete

Xnip2021-08-11_17-25-39.jpg

os_atomic_rmw_loop2o遞歸執行完會進入 _dispatch_root_queue_push

Xnip2021-08-11_17-28-33.jpg 進入_dispatch_root_queue_push_inline

Xnip2021-08-11_17-29-08.jpg

進入 _dispatch_root_queue_poke

Xnip2021-08-11_17-29-53.jpg 進入_dispatch_root_queue_poke_slow

Xnip2021-08-11_17-30-24.jpg

五.單例底層原理

待補充

六.異步函數分析下

待補充

相關文章
相關標籤/搜索