iOS 信號(hào)量機(jī)制

信號(hào)量機(jī)制

在 iOS 系統(tǒng)及大部分現(xiàn)代操作系統(tǒng)中涩盾,多個(gè)線程可以并發(fā)執(zhí)行,CPU在線程之間來(lái)回切換励背,共享某些資源春霍,提高了資源的利用率。但是我們?cè)撊绾翁幚砀鱾€(gè)線程之間的相互制約關(guān)系叶眉?比如只有一臺(tái)打印機(jī)址儒,兩個(gè)線程都需要打印文件,如果直接讓他們簡(jiǎn)單的并發(fā)訪問(wèn)打印機(jī)衅疙,那么很可能什么都打印不出來(lái)或者打印的文件是混亂的莲趣。顯然,我們需要增加一種機(jī)制來(lái)控制線程間的相互制約關(guān)系炼蛤。

打印機(jī)亂碼(圖片來(lái)源于網(wǎng)絡(luò))

簡(jiǎn)單來(lái)說(shuō)就是我們需要一種機(jī)制來(lái)控制線程執(zhí)行的先后順序妖爷。

而信號(hào)量就可以提供這樣的一種機(jī)制,讓一個(gè)臨界區(qū)(臨界區(qū)指的是線程中訪問(wèn)共用資源的程序片段)同一時(shí)間只有一個(gè)線程在訪問(wèn)它,也就是說(shuō)信號(hào)量是用來(lái)協(xié)調(diào)線程對(duì)共享資源的訪問(wèn)的絮识。

信號(hào)量可以理解為是一個(gè)資源計(jì)數(shù)器绿聘,對(duì)信號(hào)量有兩個(gè)操作來(lái)達(dá)到互斥,分別是P和V操作次舌。 一般情況是這樣進(jìn)行臨界訪問(wèn)或互斥訪問(wèn)的: 設(shè)信號(hào)量值為1熄攘, 當(dāng)一個(gè)線程A運(yùn)行時(shí),使用資源彼念,進(jìn)行P操作挪圾,即對(duì)信號(hào)量值減1,也就是資源數(shù)少了1個(gè)逐沙。這時(shí)信號(hào)量值為0哲思。系統(tǒng)中規(guī)定當(dāng)信號(hào)量值為0是,必須等待吩案,直到信號(hào)量值不為零才能繼續(xù)操作棚赔。 這時(shí)如果線程B想要運(yùn)行,那么也必須進(jìn)行P操作徘郭,但是此時(shí)信號(hào)量為0靠益,所以無(wú)法減1,即不能P操作残揉,也就阻塞胧后。這樣就達(dá)到了線程A的排他訪問(wèn)。 當(dāng)線程A運(yùn)行結(jié)束后抱环,釋放資源壳快,進(jìn)行V操作。資源數(shù)重新加1江醇,這時(shí)信號(hào)量的值變?yōu)?濒憋,這時(shí)線程B發(fā)現(xiàn)資源數(shù)不為0,信號(hào)量能進(jìn)行P操作了陶夜,立即執(zhí)行P操作。信號(hào)量值又變?yōu)?裆站,線程B有資源条辟,其余線程必須等到,達(dá)到線程B的排他訪問(wèn)宏胯。 這就是信號(hào)量來(lái)控制線程互斥的原理羽嫡。

GCD如何使用信號(hào)量

在GCD中有三個(gè)函數(shù)是semaphore的操作,分別是:

dispatch_semaphore_create(long value); // 創(chuàng)建一個(gè)semaphore 
dispatch_semaphore_signal(dispatch_semaphore_t dsema); // 發(fā)送一個(gè)信號(hào)
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); // 等到信號(hào)

第一個(gè)函數(shù)有一個(gè)長(zhǎng)整形的參數(shù)肩袍,我們可以理解為信號(hào)的總量杭棵,dispatch_semaphore_signal是發(fā)送一個(gè)信號(hào),自然會(huì)讓信號(hào)總量加1,dispatch_semaphore_wait等待信號(hào)魂爪,當(dāng)信號(hào)總量少于0的時(shí)候就會(huì)一直等待先舷,否則就可以正常的執(zhí)行,并讓信號(hào)總量-1滓侍,根據(jù)這樣的原理蒋川,我們便可以快速的創(chuàng)建一個(gè)并發(fā)控制來(lái)同步任務(wù)和有限資源訪問(wèn)控制。

// 創(chuàng)建隊(duì)列組
    dispatch_group_t group = dispatch_group_create();   
// 創(chuàng)建信號(hào)量撩笆,并且設(shè)置值為10
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);   
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);   
    for (int i = 0; i < 100; i++)   
    {   // 由于是異步執(zhí)行的捺球,所以每次循環(huán)Block里面的dispatch_semaphore_signal根本還沒(méi)有執(zhí)行就會(huì)執(zhí)行dispatch_semaphore_wait,從而semaphore-1.當(dāng)循環(huán)10此后夕冲,semaphore等于0氮兵,則會(huì)阻塞線程,直到執(zhí)行了Block的dispatch_semaphore_signal 才會(huì)繼續(xù)執(zhí)行
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);   
        dispatch_group_async(group, queue, ^{   
            NSLog(@"%i",i);   
            sleep(2);   
// 每次發(fā)送信號(hào)則semaphore會(huì)+1歹鱼,
            dispatch_semaphore_signal(semaphore);   
        });   
    }

總結(jié)

信號(hào)量是用在多線程并發(fā)的泣栈,一個(gè)線程完成了某一個(gè)動(dòng)作就通過(guò)信號(hào)量告訴別的線程,別的線程再進(jìn)行某些動(dòng)作醉冤。

參考鏈接

1.信號(hào)量與鎖的差別
2.淺談GCD中的信號(hào)量
3.用信號(hào)量解決進(jìn)程的同步與互斥探討


內(nèi)容整理自網(wǎng)絡(luò)秩霍,如有侵權(quán)請(qǐng)聯(lián)系刪除。

聯(lián)系作者:簡(jiǎn)書·DH_Fantasy 新浪微博·DH_Fantasy
版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名(CC BY-NC-ND 3.0

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蚁阳,一起剝皮案震驚了整個(gè)濱河市铃绒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌螺捐,老刑警劉巖颠悬,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異定血,居然都是意外死亡赔癌,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門澜沟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)灾票,“玉大人,你說(shuō)我怎么就攤上這事茫虽】裕” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵濒析,是天一觀的道長(zhǎng)正什。 經(jīng)常有香客問(wèn)我,道長(zhǎng)号杏,這世上最難降的妖魔是什么婴氮? 我笑而不...
    開(kāi)封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上主经,老公的妹妹穿的比我還像新娘荣暮。我一直安慰自己,他們只是感情好旨怠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布渠驼。 她就那樣靜靜地躺著,像睡著了一般鉴腻。 火紅的嫁衣襯著肌膚如雪迷扇。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天爽哎,我揣著相機(jī)與錄音蜓席,去河邊找鬼。 笑死课锌,一個(gè)胖子當(dāng)著我的面吹牛厨内,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播渺贤,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼雏胃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了志鞍?” 一聲冷哼從身側(cè)響起瞭亮,我...
    開(kāi)封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎固棚,沒(méi)想到半個(gè)月后统翩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡此洲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年厂汗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呜师。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡娶桦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汁汗,到底是詐尸還是另有隱情趟紊,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布碰酝,位于F島的核電站,受9級(jí)特大地震影響戴差,放射性物質(zhì)發(fā)生泄漏送爸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望袭厂。 院中可真熱鬧墨吓,春花似錦、人聲如沸纹磺。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)橄杨。三九已至秘症,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間式矫,已是汗流浹背乡摹。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留采转,地道東北人聪廉。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像故慈,于是被迫代替她去往敵國(guó)和親板熊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

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