1. 程式人生 > >多執行緒六:dispatch_semaphore

多執行緒六:dispatch_semaphore

一、定義

  • semaphore叫做”訊號量”
  • 訊號量的初始值,可以用來控制執行緒併發訪問的最大數量
    • 比如想要有3個執行緒同時執行任務,訊號量的初始值就寫3.
  • 訊號量的初始值為1,代表同時只允許1條執行緒訪問資源,保證執行緒同步

程式碼: 在這裡插入圖片描述

例子: 在這裡插入圖片描述

// 執行緒10、7、6、9、8
- (void)test
{
    // 如果訊號量的值 > 0,就讓訊號量的值減1,然後繼續往下執行程式碼
    // 如果訊號量的值 <= 0,就會休眠等待,直到訊號量的值變成>0,就讓訊號量的值減1,然後繼續往下執行程式碼
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    
   // 在這中間寫要執行的程式碼
   
    // 讓訊號量的值+1
    dispatch_semaphore_signal(self.semaphore);
}

  • dispatch_semaphore_signal的宣告為: * long dispatch_semaphore_signal(dispatch_semaphore_t dsema) * 這個函式會使傳入的訊號量dsema的值加1;(至於返回值,待會兒再講)

  • dispatch_semaphore_wait的宣告為: * long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); * 這個函式會使傳入的訊號量dsema的值減1; * 這個函式的作用是這樣的,如果dsema訊號量的值大於0,該函式所處執行緒就繼續執行下面的語句,並且將訊號量的值減1; * 如果desema的值為0,那麼這個函式就阻塞當前執行緒等待timeout(注意timeout的型別為dispatch_time_t,不能直接傳入整形或float型數),如果等待的期間desema的值被dispatch_semaphore_signal函式加1了,且該函式(即dispatch_semaphore_wait)所處執行緒獲得了訊號量,那麼就繼續向下執行並將訊號量減1。 * 如果等待期間沒有獲取到訊號量或者訊號量的值一直為0,那麼等到timeout時,其所處執行緒自動執行其後語句。

  • dispatch_semaphore_signal的返回值為long型別,當返回值為0時表示當前並沒有執行緒等待其處理的訊號量,其處理的訊號量的值加1即可。當返回值不為0時,表示其當前有(一個或多個)執行緒等待其處理的訊號量,並且該函式喚醒了一個等待的執行緒(當執行緒有優先順序時,喚醒優先順序最高的執行緒;否則隨機喚醒)。

  • dispatch_semaphore_wait的返回值也為long型。當其返回0時表示在timeout之前,該函式所處的執行緒被成功喚醒。當其返回不為0時,表示timeout發生。

  • 在設定timeout時,比較有用的兩個巨集:DISPATCH_TIME_NOW 和 DISPATCH_TIME_FOREVER。

    • DISPATCH_TIME_NOW  表示當前;
    • DISPATCH_TIME_FOREVER  表示遙遠的未來;
    • 一般可以直接設定timeout為這兩個巨集其中的一個,或者自己建立一個dispatch_time_t型別的變數。
    • 建立dispatch_time_t型別的變數有兩種方法,dispatch_time和dispatch_walltime。
    • 利用建立dispatch_time建立dispatch_time_t型別變數的時候一般也會用到這兩個變數。

dispatch_time的宣告如下: * dispatch_time_t dispatch_time(dispatch_time_t when, int64_t delta); * 其引數when需傳入一個dispatch_time_t型別的變數,和一個delta值。表示when加delta時間就是timeout的時間。 * 例如:dispatch_time_t t = dispatch_time(DISPATCH_TIME_NOW, 110001000*1000); * 表示當前時間向後延時一秒為timeout的時間。

  • 關於訊號量,一般可以用停車來比喻。
    • 停車場剩餘4個車位,那麼即使同時來了四輛車也能停的下。如果此時來了五輛車,那麼就有一輛需要等待。
    • 訊號量的值就相當於剩餘車位的數目,dispatch_semaphore_wait函式就相當於來了一輛車,dispatch_semaphore_signal 就相當於走了一輛車。停車位的剩餘數目在初始化的時候就已經指明瞭(dispatch_semaphore_create(long value)),

呼叫一次dispatch_semaphore_signal,剩餘的車位就增加一個;呼叫一次dispatch_semaphore_wait剩餘車位就減少一個;

當剩餘車位為0時,再來車(即呼叫dispatch_semaphore_wait)就只能等待。有可能同時有幾輛車等待一個停車位。有些車主

沒有耐心,給自己設定了一段等待時間,這段時間內等不到停車位就走了,如果等到了就開進去停車。而有些車主就像把車停在這,

所以就一直等下去。