dispatch_semaphore使用

想象種場景:1.要下載十個文件舵变,但是同一時刻只想讓兩個文件處于下載狀態(tài),用
GCD如何實現(xiàn)?
這種問題涉及到對并發(fā)的控制瘦穆,使用信號量就可以很好的控制纪隙。
信號量是一個整形值并且具有一個初始計數(shù)值,并且支持兩個操作:信號通知和等待扛或。當(dāng)一個信號量被信號通知绵咱,其計數(shù)會被增加。當(dāng)一個線程在一個信號量上等待時熙兔,線程會被阻塞(如果有必要的話)悲伶,直至計數(shù)器大于零艾恼,然后線程會減少這個計數(shù)。
在GCD中有三個函數(shù)是關(guān)于semaphore的操作麸锉,分別是:

  dispatch_semaphore_create   創(chuàng)建一個semaphore
  dispatch_semaphore_signal   發(fā)送一個信號,使信號量+1
  dispatch_semaphore_wait    等待信號

不要看他們的樣子很生疏钠绍,這個semaphore單詞還不認(rèn)識,感覺很晦澀花沉,其實真正用的時候就會發(fā)現(xiàn)還是很簡單的柳爽。這套API簡單到就3個函數(shù),函數(shù)的參數(shù)一般也就一兩個主穗。
信號量可以拿停車場的例子來類比泻拦,方便理解。
假如有一個停車場有3個空車位忽媒,停車場外面有個信號燈顯示著有3個空位争拐,這時停車場外面來了五輛車,前三量車依次進(jìn)入停車場晦雨,每進(jìn)入一輛車架曹,信號燈都要減1,當(dāng)信號燈減成0的時候就意味著沒有車位了闹瞧,外面的車只能等待绑雄,不得進(jìn)入停車場。 而當(dāng)一輛車開走的時候奥邮,信號燈上又會加1万牺,意味著有空車位了,就可以有一輛車進(jìn)入洽腺。dispatch_queue_create就是創(chuàng)建信號脚粟,dispatch_semaphore_wait就是在停車場外鳴笛,準(zhǔn)備進(jìn)入停車場蘸朋,此時如果有空余車外邑茄,可以順利進(jìn)入胰丁,并讓信號燈減1,加入沒有車位缘回,就一直在外面等車秕硝,直到信號燈數(shù)量大于1時候就馬上進(jìn)入 dispatch_semaphore_signal就是讓信號燈數(shù)量+1,如果外面有等待的車輛次哈, 就告訴它可以進(jìn)來了莹规。

一 .API介紹

1.dispatch_semaphore_create

/*!
 * @function dispatch_semaphore_create
 *
 * @abstract
 * Creates new counting semaphore with an initial value.
 * 使用初始化值創(chuàng)建一個新的計數(shù)信號量
 * @discussion
 * Passing zero for the value is useful for when two threads need to reconcile
 * the completion of a particular event. Passing a value greater than zero is
 * useful for managing a finite pool of resources, where the pool size is equal
 * to the value.
 * 傳0用于 兩個線程需要以特定順序完成某個事件请梢,傳大于0的數(shù)用于管理資源,資源池的資源數(shù)要和傳入的值一致
 * @param value
 * The starting value for the semaphore. Passing a value less than zero will
 * cause NULL to be returned.
 * 信號量初始值。傳入低于0的值會返回NULL
 * @result
 * The newly created semaphore, or NULL on failure.
 */
dispatch_semaphore_t
dispatch_semaphore_create(long value);

2.dispatch_semaphore_wait

/*!
 * @function dispatch_semaphore_wait
 *
 * @abstract
 * Wait (decrement) for a semaphore.
 *  等待(降低)信號量
 * @discussion
 * Decrement the counting semaphore. If the resulting value is less than zero,
 * this function waits for a signal to occur before returning.
 * 降低信號量辐马。如果返回值小于0佑惠,該函數(shù)會阻塞 等待直到信號發(fā)生才能返回
 * @param dsema
 * The semaphore. The result of passing NULL in this parameter is undefined.
 *  信號對象。傳NULL會發(fā)生不確定結(jié)果
 * @param timeout
 * When to timeout (see dispatch_time). As a convenience, there are the
 * DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
 *  超時時間齐疙。為了方便膜楷,系統(tǒng)提供了兩個常亮:DISPATCH_TIME_NOW和DISPATCH_TIME_FOREVER
 * @result
 * Returns zero on success, or non-zero if the timeout occurred.
 * 返回0代表成功,返回非0代表超時時間到達(dá)了
 */
long
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);

3.dispatch_semaphore_signal

/*!
 * @function dispatch_semaphore_signal
 *
 * @abstract
 * Signal (increment) a semaphore.
 *  發(fā)送(增加)一個信號量
 * @discussion
 * Increment the counting semaphore. If the previous value was less than zero,
 * this function wakes a waiting thread before returning.
 * 這個方法喚醒一個等待的線程 然后返回
 * @param dsema The counting semaphore.
 * The result of passing NULL in this parameter is undefined.
 *  傳0是未定義的
 * @result
 * This function returns non-zero if a thread is woken. Otherwise, zero is
 * returned.
 *  返回非0代表有線程被喚醒贞奋。否則赌厅,返回0
 */
long
dispatch_semaphore_signal(dispatch_semaphore_t dsema);

二.應(yīng)用

應(yīng)用也很簡單了

    //創(chuàng)建信號量  初始化為0
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    _semaphore = semaphore;
    
    for (int i = 0; i < 10; i ++ ) {
        
        dispatch_async(globalqueue, ^{
            
            //執(zhí)行任務(wù)會使信號量減1,當(dāng)執(zhí)行兩個任務(wù)后轿塔,信號量變?yōu)?特愿,無法在繼續(xù)執(zhí)行。
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            sleep(3);
            NSLog(@"---------任務(wù)%d完成---%@",i,[NSThread currentThread]);
            //執(zhí)行完任務(wù)后勾缭,使信號量加1揍障,繼續(xù)執(zhí)行后面任務(wù)
            dispatch_semaphore_signal(semaphore);
            
        });
    }

使用for循環(huán)將十個任務(wù)添加到并行隊列中,正常情況下俩由,十個任務(wù)會同時執(zhí)行毒嫡。使用dispatch_semaphore就可以控制同一時刻只能有兩個任務(wù)在執(zhí)行。

dispatch_semaphore也可以控制兩個任務(wù)的執(zhí)行順序幻梯,比如任務(wù)1 和任務(wù)2 兜畸,創(chuàng)建一個出事信號量為0的semaphore對象,在任務(wù)1前面使用dispatch_semaphore_wait函數(shù)阻塞碘梢,等待信號量大于0 當(dāng)任務(wù)2完成的時候發(fā)送信號咬摇,使任務(wù)1執(zhí)行。 這樣就可以控制任務(wù)2先完成,任務(wù)1后完成煞躬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肛鹏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子恩沛,更是在濱河造成了極大的恐慌在扰,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件复唤,死亡現(xiàn)場離奇詭異健田,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)佛纫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門妓局,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呈宇,你說我怎么就攤上這事好爬。” “怎么了甥啄?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵存炮,是天一觀的道長。 經(jīng)常有香客問我,道長穆桂,這世上最難降的妖魔是什么宫盔? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮享完,結(jié)果婚禮上灼芭,老公的妹妹穿的比我還像新娘。我一直安慰自己般又,他們只是感情好彼绷,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著茴迁,像睡著了一般寄悯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堕义,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天猜旬,我揣著相機(jī)與錄音,去河邊找鬼胳螟。 笑死昔馋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的糖耸。 我是一名探鬼主播秘遏,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嘉竟!你這毒婦竟也來了邦危?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤舍扰,失蹤者是張志新(化名)和其女友劉穎倦蚪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體边苹,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡陵且,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了个束。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片慕购。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖茬底,靈堂內(nèi)的尸體忽然破棺而出沪悲,到底是詐尸還是另有隱情,我是刑警寧澤阱表,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布殿如,位于F島的核電站贡珊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涉馁。R本人自食惡果不足惜门岔,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谨胞。 院中可真熱鬧固歪,春花似錦、人聲如沸胯努。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叶沛。三九已至,卻和暖如春忘朝,著一層夾襖步出監(jiān)牢的瞬間灰署,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工局嘁, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留溉箕,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓悦昵,卻偏偏與公主長得像肴茄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子但指,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Managing Units of Work(管理工作單位) 調(diào)度塊允許您直接配置隊列中各個工作單元的屬性寡痰。它們還...
    edison0428閱讀 7,970評論 0 1
  • dispatch_semaphore是GCD用來同步的一種方式,dispatch_semaphore 信號量基于計...
    e5a8d3183387閱讀 327評論 0 1
  • 本文為轉(zhuǎn)載資料棋凳,原文地址: http://www.reibang.com/p/02821f9d7777 一拦坠、信號量...
    一曰就是一天閱讀 1,135評論 0 3
  • 1. 并行和并發(fā) 簡單來說,若說兩個任務(wù)A和B并發(fā)執(zhí)行剩岳,則表示任務(wù)A和任務(wù)B在同一時間段里被執(zhí)行(更多的可能是二者...
    Z_Han閱讀 639評論 0 8
  • 下雨了 百無聊賴的日子 我想唱首老情歌 給你聽 時光飛逝 一去就不回頭 不知不覺中 我們度過了多少春秋 路過你的 ...
    Harvest收獲閱讀 495評論 48 53