iOS中的多執行緒(關於GCD 的佇列組)

語言: CN / TW / HK

highlight: a11y-dark theme: cyanosis


「這是我參與11月更文挑戰的第8天,活動詳情檢視:2021最後一次更文挑戰

GCD佇列組

有時候會有這樣的需求:分別非同步執行2個耗時任務,然後當2個耗時任務都執行完畢後再回到主執行緒執行任務。這時候可以用到 GCD 的佇列組

  • 使用 dispatch_group_create 建立一個佇列組
  • 使用 dispatch_group_async 將任務新增到佇列中

dispatch_group_notify

  • 監聽 group 中任務的完成狀態,當 group 中所有的任務都執行完成後,就會收到 dispatch_group_notify 通知
  • 使用 dispatch_group_notify,不會阻塞當前執行緒

示例: ```js //建立一個佇列組 dispatch_group_t group = dispatch_group_create();

//建立一個佇列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

NSLog(@"當前執行緒--0--%@",[NSThread currentThread]);

//將任務放到佇列中 dispatch_group_async(group, queue, ^{ for (NSInteger i = 0; i<3; i++) { NSLog(@"任務1----%@",[NSThread currentThread]); } });

//將任務放到佇列中 dispatch_group_async(group, queue, ^{ for (NSInteger i = 0; i<3; i++) { NSLog(@"任務2----%@",[NSThread currentThread]); } });

//當這個佇列組的所有佇列全部完成,就會收到這個訊息 dispatch_group_notify(group, queue, ^{ NSLog(@"1和2執行完畢 -- %@",[NSThread currentThread]); });

NSLog(@"當前執行緒--3--%@",[NSThread currentThread]); ```

log:

Snip20211107_73.png

dispatch_group_wait

  • 監聽 group 中任務的完成狀態,當 group 中所有的任務都執行完成後,就會收到 dispatch_group_notify 通知
  • 使用 dispatch_group_notify,會阻塞當前執行緒

示例: ```js //建立一個佇列組 dispatch_group_t group = dispatch_group_create();

//建立一個佇列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

NSLog(@"當前執行緒--0--%@",[NSThread currentThread]);

//將任務放到佇列中 dispatch_group_async(group, queue, ^{ for (NSInteger i = 0; i<3; i++) { NSLog(@"任務1----%@",[NSThread currentThread]); } });

//將任務放到佇列中 dispatch_group_async(group, queue, ^{ for (NSInteger i = 0; i<3; i++) { NSLog(@"任務2----%@",[NSThread currentThread]); } });

//設定dispatch_group_wait dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

//阻塞當前執行緒,當這個佇列組的所有佇列全部完成,才會繼續執行 NSLog(@"當前執行緒--3--%@",[NSThread currentThread]); ``` log:

Snip20211107_74.png

dispatch_group_enter 和 dispatch_group_leave

  • dispatch_group_enter 標誌一個任務追加到 group,執行一次,相當於 group 中未執行完畢任務數 +1

  • dispatch_group_leave 標誌著一個任務離開了 group,執行一次,相當於 group 中未執行完畢任務數 -1

  • dispatch_group_enterdispatch_group_leave 組合,其實等同於 dispatch_group_async

  • group 中未執行完畢任務數為 0 的時,才會使 dispatch_group_wait 解除阻塞,以及執行追加到 dispatch_group_notify 中的任務

示例: ```js //建立一個佇列組 dispatch_group_t group = dispatch_group_create();

//建立一個佇列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

NSLog(@"當前執行緒--0--%@",[NSThread currentThread]);

//將任務放到佇列組 dispatch_group_enter(group); dispatch_async(queue, ^{ for (NSInteger i = 0; i<3; i++) { NSLog(@"任務1----%@",[NSThread currentThread]); }

//將任務拿出佇列組
dispatch_group_leave(group);

});

//將任務放到佇列組 dispatch_group_enter(group); dispatch_async(queue, ^{ for (NSInteger i = 0; i<3; i++) { NSLog(@"任務2----%@",[NSThread currentThread]); }

//將任務拿出佇列組
dispatch_group_leave(group);

});

//設定dispatch_group_wait dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

//阻塞當前執行緒,當這個佇列組的所有佇列全部完成,才會繼續執行 NSLog(@"當前執行緒--3--%@",[NSThread currentThread]); ``` log: Snip20211107_75.png