標籤:常見 就會 回調 map time send obj create 上傳
dispatch_semaphore_t
用法,dispatch_semaphore_create
建立訊號量實際就是建立的對象設定最大並發數.不得小於0, 小於0導致崩潰,dispatch_semaphore_wait
, 減少一個訊號量, 比如建立的對象訊號量是5, wait一次就減少一個訊號量,訊號量變為4, 當訊號量為0的時候當前線程就會等待,直到訊號量>0的時候才會往下進行.dispatch_semaphore_signal
增加一個訊號量,減少與增加訊號量是成對出現的.
dispatch_semaphore_t semap = dispatch_semaphore_create(1); // 控制最大並發數1條新線程 此時下面操作是安全執行緒的dispatch_semaphore_wait(semap, DISPATCH_TIME_FOREVER);// 此時訊號量由1 變為 0 ,即使下面有任務也不會再執行, 因為訊號量為0// 單個線程操作地區... 安全執行緒dispatch_semaphore_signal(semap);
- 第一種常見用法
group + queue
使用情境: 單次, 多個任務同時執行, 自動開啟多個線程,最後執行完畢在回調處理執行完畢的結果
- 缺點: 不能控制最大並發數, 操作同一資源不安全
// DISPATCH_QUEUE_CONCURRENT 產生一個並發隊列(可以有多條線程) dispatch_queue_t queue = dispatch_queue_create("sendrequest", DISPATCH_QUEUE_CONCURRENT); // 建立group dispatch_group_t group = dispatch_group_create();// 多個耗時任務同時進行 加入group中同時進行,執行完畢監聽回調 dispatch_group_async(group, queue, ^{ NSLog(@"1"); sleep(2); NSLog(@"1+"); }); dispatch_group_async(group, queue, ^{ NSLog(@"2"); }); dispatch_group_async(group, queue, ^{ NSLog(@"3"); }); // group任務全部執行完畢回調 dispatch_group_notify(group, queue, ^{ NSLog(@"done"); });
- 第二種使用情境
semaphore + queue
情境: 多次(有100個任務需要執行, 例如資料庫100條資料,需要上傳,每條建立一個任務,開2個線程), 控制最大並發數(後台開2個線程), group中不能控制最大並發數, 操作資料線程加鎖,保證安全執行緒
- 缺點不能處理回調
dispatch_semaphore_t semap = dispatch_semaphore_create(2); // 控制最大並發數2條新線程 // DISPATCH_QUEUE_CONCURRENT 產生一個並發隊列(可以有多條線程) dispatch_queue_t queue = dispatch_queue_create("sendrequest", DISPATCH_QUEUE_CONCURRENT); // 10個任務, 最大並發2, for (int i = 0; i < 10; i++) { dispatch_async(queue, ^{ dispatch_semaphore_wait(semap, DISPATCH_TIME_FOREVER); // 線程操作地區 dispatch_semaphore_signal(semap); }); }
- 第三種情境組合用法:
dispatch_semaphore_t(設定最大並發數) + dispatch_queue_t(建立並發隊列) + dispatch_group_t(監聽任務完成回調)
可以處理任務完成回調, 可設定最大並發數
dispatch_semaphore_t semap = dispatch_semaphore_create(2); // 控制最大並發數2條新線程 // DISPATCH_QUEUE_CONCURRENT 產生一個並發隊列(可以有多條線程) dispatch_queue_t queue = dispatch_queue_create("sendrequest", DISPATCH_QUEUE_CONCURRENT); dispatch_group_t group = dispatch_group_create(); for (int i = 0; i < 10; i++) { dispatch_group_async(group, queue, ^{ dispatch_semaphore_wait(semap, DISPATCH_TIME_FOREVER); // 線程操作地區 最多有兩個線程在此做事情 dispatch_semaphore_signal(semap); }); } // group任務全部執行完畢回調 dispatch_group_notify(group, queue, ^{ NSLog(@"done"); });
iOS-多線程dispatch_semaphore_t dispatch_queue_t dispatch_group_t常見用法情境