GCD 信號量控制併發 (dispatch_semaphore)

當我們在處理一系列線程的時候,當數量達到一定量,在以前我們可能會選擇使用NSOperationQueue來處理併發控制,但如何在GCD中快速的控制併發呢?答案就是dispatch_semaphore,對經常做unix開發的人來講,我所介紹的內容可能就顯得非常入門級了,信號量在他們的多線程開發中再平常不過了。
  信號量是一個整形值並且具有一個初始計數值,並且支持兩個操作:信號通知和等待。當一個信號量被信號通知,其計數會被增加。當一個線程在一個信號量上等待時,線程會被阻塞(如果有必要的話),直至計數器大於零,然後線程會減少這個計數。
  在GCD中有三個函數是semaphore的操作,分別是:
  dispatch_semaphore_create   創建一個semaphore
  dispatch_semaphore_signal   發送一個信號
  dispatch_semaphore_wait    等待信號
  簡單的介紹一下這三個函數,第一個函數有一個整形的參數,我們可以理解爲信號的總量,dispatch_semaphore_signal是發送一個信號,自然會讓信號總量加1,dispatch_semaphore_wait等待信號,當信號總量少於0的時候就會一直等待,否則就可以正常的執行,並讓信號總量-1,根據這樣的原理,我們便可以快速的創建一個併發控制來同步任務和有限資源訪問控制。
  1. dispatch_group_t group = dispatch_group_create();   
  2.     dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);   
  3.     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);   
  4.     for (int i = 0; i < 100; i++)   
  5.     {   
  6.         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);   
  7.         dispatch_group_async(group, queue, ^{   
  8.             NSLog(@"%i",i);   
  9.             sleep(2);   
  10.             dispatch_semaphore_signal(semaphore);   
  11.         });   
  12.     }   
  13.     dispatch_group_wait(group, DISPATCH_TIME_FOREVER);   
  14.     dispatch_release(group);   
  15.     dispatch_release(semaphore);   

  簡單的介紹一下這一段代碼,創建了一個初使值爲10的semaphore,每一次for循環都會創建一個新的線程,線程結束的時候會發送一個信號,線程創建之前會信號等待,所以當同時創建了10個線程之後,for循環就會阻塞,等待有線程結束之後會增加一個信號才繼續執行,如此就形成了對併發的控制,如上就是一個併發數爲10的一個線程隊列。


簡單示例

 

  1. __block BOOL isok = NO;  
  2.       
  3.     dispatch_semaphore_t sema = dispatch_semaphore_create(0);  
  4.     Engine *engine = [[Engine alloc] init];  
  5.     [engine queryCompletion:^(BOOL isOpen) {  
  6.         isok = isOpen;  
  7.         dispatch_semaphore_signal(sema);  
  8.     } onError:^(int errorCode, NSString *errorMessage) {  
  9.         isok = NO;  
  10.         dispatch_semaphore_signal(sema);  
  11.     }];  
  12.       
  13.     dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);  
  14.     dispatch_release(sema);  
發佈了76 篇原創文章 · 獲贊 13 · 訪問量 65萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章