iOS 多线程: 信号量
生活随笔
收集整理的這篇文章主要介紹了
iOS 多线程: 信号量
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
今天跟大家聊聊關于 GCD 中的信號量的使用.
網上有很多關于信號量的介紹, 這里只是結合本人一些理解和實際使用來分享給大家.
在GCD中有三個函數是semaphore的操作,分別是
1.創建一個semaphore
dispatch_semaphore_create
2. 發送一個信號
dispatch_semaphore_signal
會使信號量計數增加1.
3. 等待信號
dispatch_semaphore_wait
會使信號量計數減少1.
/usr/include/dispatch/semaphore.h 中關于函數的聲明和定義, 注釋很清晰.
這里特別需要注意的幾個問題:
dispatch_semaphore_t dispatch_semaphore_create(long value);
函數需要傳入一個大于或者等于0的值, 傳入小于0的值, 函數返回 NULL.
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
返回0表示成功, 非0表示超時, 會繼續執行該函數后面的語句.
關于參數 timeout, 后面細說.
long dispatch_semaphore_signal(dispatch_semaphore_t dsema);
返回非0值表示成功喚醒線程, 0表示沒有喚醒.
下面結合實際應用場景, 說說信號量的使用和注意事項.
在開發過程中, 大家應該會有這樣的需求
場景1:
等待上一個網絡請求的返回結果, 再決定是否進行下一個網絡請求.
示例代碼:
dispatch_semaphore_t sema = dispatch_semaphore_create(0); [NetReq request:^(BOOL ok) { // 喚醒等待的線程dispatch_semaphore_signal(sema); } onFail:^(int errorCode, NSString *errorMessage) { // 喚醒等待的線程dispatch_semaphore_signal(sema); }]; // 一直等待 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); // 等待上面網絡請求結束, 開始執行下面語句 [NetReq request...]場景2:
生產者和消費者問題
使用信號量可以解決該類型的問題.
示例代碼
dispatch_semaphore_t signal = dispatch_semaphore_create(0);if (NULL == signal) {return; }//消費者隊列 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{while (true) {// 在超時時間內成功得到信號觸發返回0值表示成功, 非0表示失敗// 超時時間設置為DISPATCH_TIME_FOREVER, 表示一直等待, 其后語句被阻塞, 一直等到其被喚醒// DISPATCH_TIME_NOW, 表示不等待, 繼續執行其后面的語句// 也可以指定時間, dispatch_time(DISPATCH_TIME_NOW, 10*NSEC_PER_SEC)), 表示10s內等待, 超過10s, 繼續執行下面語句long result = dispatch_semaphore_wait(signal, DISPATCH_TIME_NOW);// 超時了if (result != 0) {continue;}// 被喚醒NSLog(@"1....消費 %@", self.lockData);[self.lockData removeObjectAtIndex:0];}});// 這里可以阻塞一段時間, 延時增加信號量來看看消費者隊列中 wait 的情況sleep(5);//生產者隊列 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{while (true) {[self.lockData addObject:@"0"];NSLog(@"0-------產出: %@", self.lockData);// 使信號量加1, 返回非0表示成功, 0表示失敗long result = dispatch_semaphore_signal(signal);//失敗if (0 == result) {//wait for a whilesleep(1);continue;}//成功//TODO:}});關于超時參數的定義在注釋中有詳細說明.
現在你可以動手試一試了.
總結
以上是生活随笔為你收集整理的iOS 多线程: 信号量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北京邮电大学计算机学院就业信息,北京邮电
- 下一篇: Pr 入门系列之四:编辑(基础篇)