第十章 Posix信號(hào)量

知乎討論

通俗的描述信號(hào)量丧荐,是這么個(gè)東西:
每個(gè)信號(hào)量擁有一個(gè)計(jì)數(shù)器陪捷,sem_post()可以使該計(jì)數(shù)器+1V操作)九杂,sem_wait()在計(jì)數(shù)器不為0時(shí)迷帜,可以使該計(jì)數(shù)器-1,否則阻塞直到不為0(P操作)惨奕。
而該計(jì)數(shù)器的存在识颊,就可以限定某個(gè)容器中元素的個(gè)數(shù)允耿。

如果單純的看效果奕删,互斥量+條件變量可以實(shí)現(xiàn)計(jì)數(shù)器為1的信號(hào)量。

優(yōu)缺點(diǎn)

UNP卷二

作者對(duì)于信號(hào)量的評(píng)價(jià)為:

  1. 信號(hào)量默認(rèn)就是進(jìn)程間共享
    對(duì)同一個(gè)信號(hào)量疗认,加鎖和解鎖可以在不同的進(jìn)程或是進(jìn)程進(jìn)行完残。
    而互斥量只能有是由加鎖線(xiàn)程解鎖,且默認(rèn)不再進(jìn)程間共享横漏。
  2. 信號(hào)量有與之關(guān)聯(lián)的一個(gè)值谨设,計(jì)數(shù)器
    該值在信號(hào)量結(jié)構(gòu)體內(nèi)部維護(hù)。即使消費(fèi)者還沒(méi)有阻塞在sem_wait()缎浇,該值也會(huì)遞增扎拣。
    相比與條件變量,如果消費(fèi)者還沒(méi)阻塞在pthread_cond_wait()素跺,那么由pthread_cond_signal()發(fā)送的信號(hào)就會(huì)丟失二蓝,沒(méi)有函數(shù)去處理。
  3. 相比于其他鎖指厌,只有sem_port()是異步信號(hào)安全函數(shù)
    異步信號(hào)安全函數(shù)指的是:可以在信號(hào)處理函數(shù)中調(diào)用的函數(shù)刊愚。

muduo陳碩

  1. 信號(hào)量不是必備的鎖
    使用條件標(biāo)量和互斥量可以完全代替信號(hào)量的功能
  2. 信號(hào)量的計(jì)數(shù)器是個(gè)累贅
    程序的容器有自己的長(zhǎng)度,而信號(hào)量又自帶一個(gè)踩验,這樣造成了同樣的信息維護(hù)兩份鸥诽,需要時(shí)刻保持一致商玫。增大了程序員的負(fù)擔(dān)和出錯(cuò)的可能。
  3. 同時(shí)建議使用單獨(dú)一個(gè)線(xiàn)程去分配任務(wù)
    其他線(xiàn)程使用條件變量阻塞

個(gè)人見(jiàn)解

沒(méi)有項(xiàng)目經(jīng)驗(yàn)牡借,不保證全對(duì)

  1. 不同線(xiàn)程間可解鎖
    這還真可能是個(gè)累贅拳昌。
  2. 確實(shí)可以使用條件變量+互斥量去代替
  3. 異步信號(hào)安全函數(shù)
    沒(méi)用過(guò),不知道啊钠龙。書(shū)上也將炬藤,可以在函數(shù)內(nèi)向管道內(nèi)寫(xiě)東西的方式來(lái)激活一個(gè)別的線(xiàn)程,解決這些問(wèn)題俊鱼。

Posix 信號(hào)量

Posix信號(hào)量不必在內(nèi)核中維護(hù)刻像。

有名信號(hào)量

這個(gè)信號(hào)量有名字啦,根據(jù)這個(gè)名字就可以在不同的進(jìn)程間使用并闲。

這個(gè)名字可以時(shí)文件系統(tǒng)中對(duì)應(yīng)的名字來(lái)表示细睡。

Api

打開(kāi)/創(chuàng)建有名信號(hào)量

#include <semaphore.h>
sem_t sem;
sem_t *sem_open(const char *pathfile, int flag/, mode_t mode ,unsigned int value/);

打開(kāi)一個(gè)信號(hào)量
flag:可以時(shí)0,主要使用來(lái),當(dāng)指定的文件不存在時(shí)帝火,使用O_CREATE | O_EXEL新建溜徙,如果指定為0,后兩個(gè)參數(shù)可省略,否則后面兩個(gè)參數(shù)需要帶上犀填。
mode:文件權(quán)限蠢壹。
value:信號(hào)量初始的值,這這個(gè)參數(shù)只有在新創(chuàng)建的時(shí)候才需要設(shè)置九巡,如果是打開(kāi)已有的图贸,不需要在去指定,否則會(huì)報(bào)錯(cuò)冕广。該值不超過(guò)是SEM_VALUE_MAX(至少是32767)疏日。
取消對(duì)信號(hào)量的使用

#include <semaphore.h>
int sem_close(sem_t *sem);
//成功返回0,否則返回-1

這個(gè)函數(shù)只是聲明撒汉,在這個(gè)進(jìn)程中不再使用這個(gè)信號(hào)量沟优,并不是去析構(gòu)該信號(hào)量。
同時(shí)進(jìn)程結(jié)束的時(shí)候睬辐,無(wú)論是正常還是信號(hào)中斷退出進(jìn)程挠阁,內(nèi)核都會(huì)主動(dòng)調(diào)用該函數(shù)去關(guān)閉進(jìn)程使用的信號(hào)量。
即使都沒(méi)有后進(jìn)程在使用這個(gè)信號(hào)量了溯饵,內(nèi)核也會(huì)維持這個(gè)信號(hào)量侵俗。
也就是說(shuō),Posix的信號(hào)量是隨著內(nèi)核持續(xù)的丰刊。
主動(dòng)析構(gòu)信號(hào)量

#include <semaphore.h>
int sem_unlink(const char *name);
//成功返回0,否則-1

對(duì)打開(kāi)的信號(hào)量的路徑執(zhí)行坡慌,直接刪除指定的文件,但是并不析構(gòu)該信號(hào)量藻三。當(dāng)最后一個(gè)使用該信號(hào)量的進(jìn)程調(diào)用sem_close()對(duì)該信號(hào)量的時(shí)候洪橘,內(nèi)核析構(gòu)該信號(hào)量跪者。

P操作

#include <semaphore.h>
int sme_wait(sem_t *);
int sem_trywait(sem_t *);
//成功返回0 ,否則-1

sem_wait()測(cè)試指定的信號(hào)量,如果計(jì)數(shù)器值大于0,那么遞減計(jì)數(shù)器熄求,并立即返回渣玲,否則,阻塞在計(jì)數(shù)器為0弟晚。直到不是0時(shí)忘衍,遞減并返回。如果因?yàn)樾盘?hào)中斷,則過(guò)返回EAGAIN錯(cuò)誤卿城。
sem_trywait()函數(shù)枚钓,如果指定信號(hào)量的計(jì)數(shù)器為0,那么直接返回EAGAIN錯(cuò)誤。

為什么阻塞遞減叫做P操作瑟押?源自荷蘭單詞proberen意思是嘗試搀捷。
V操作

#include <semaphore.h>
int sme_post(sem_t *);
//成功返回0 ,否則-1

遞增指定的信號(hào)量計(jì)數(shù)器+1
同樣因?yàn)楹商m單詞verhogen增加的意思。

當(dāng)前計(jì)數(shù)器的值

#include <semaphore.h>
int sem_getvalue(sem_t *,int *);
//成功返回0 ,否則-1

傳入兩個(gè)參數(shù)多望,第二個(gè)參數(shù)是需要填充的嫩舟。
如果當(dāng)前信號(hào)量已經(jīng)上鎖,也就是有線(xiàn)程在等待怀偷,那么該值為0或者是負(fù)數(shù)家厌,而如果是負(fù)數(shù),那么表示等待該信號(hào)量解鎖的線(xiàn)程數(shù)椎工。

信號(hào)量死鎖

主要出現(xiàn)在饭于,如果同時(shí)使用兩個(gè)信號(hào)量,那么順序一定不能出錯(cuò)维蒙。

基于內(nèi)存信號(hào)量

不使用文件系統(tǒng)標(biāo)識(shí)掰吕,直接存在程序運(yùn)行的內(nèi)存中,(非共享內(nèi)存)木西。
這樣就造成了畴栖,不同進(jìn)程之間不能訪(fǎng)問(wèn)随静,不能用于不同進(jìn)程之間相互訪(fǎng)問(wèn)八千。
一個(gè)父進(jìn)程初始化一個(gè)信號(hào)量,然后fork其副本得到的是該信號(hào)量的副本燎猛,這兩個(gè)信號(hào)量之間并不存在關(guān)系恋捆。
初始化

#include <semaphore.h >
int sem_init(sem_t *sem,int shared,unsignel int value);
//出錯(cuò)返回-1,成功的不一定。
int sem_destory(sem_t *);
//成功0,失敗-1;

第二個(gè)參數(shù)重绷,表示是否在進(jìn)程件共享沸停,在這種實(shí)現(xiàn)中不可能進(jìn)程間共享,需要基于共享內(nèi)存的信號(hào)量昭卓,才可以愤钾。
sem_init()需要用戶(hù)自己創(chuàng)建一個(gè)結(jié)構(gòu)體(不是指針)瘟滨。然后使用該函數(shù)去初始化結(jié)構(gòu)體。
sem_open()則可以直接返回一個(gè)指針能颁,并不需要去創(chuàng)建這個(gè)結(jié)構(gòu)體杂瘸。

基于共享內(nèi)存的信號(hào)量

和共享內(nèi)存有關(guān)了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市伙菊,隨后出現(xiàn)的幾起案子败玉,更是在濱河造成了極大的恐慌,老刑警劉巖镜硕,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件运翼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡兴枯,警方通過(guò)查閱死者的電腦和手機(jī)血淌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)念恍,“玉大人六剥,你說(shuō)我怎么就攤上這事》寤铮” “怎么了疗疟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)瞳氓。 經(jīng)常有香客問(wèn)我策彤,道長(zhǎng),這世上最難降的妖魔是什么匣摘? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任店诗,我火速辦了婚禮,結(jié)果婚禮上音榜,老公的妹妹穿的比我還像新娘庞瘸。我一直安慰自己,他們只是感情好赠叼,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布擦囊。 她就那樣靜靜地躺著,像睡著了一般嘴办。 火紅的嫁衣襯著肌膚如雪瞬场。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,749評(píng)論 1 289
  • 那天涧郊,我揣著相機(jī)與錄音贯被,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛彤灶,可吹牛的內(nèi)容都是我干的看幼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼幌陕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼桌吃!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起苞轿,我...
    開(kāi)封第一講書(shū)人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤茅诱,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后搬卒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體瑟俭,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年契邀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了摆寄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡坯门,死狀恐怖微饥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情古戴,我是刑警寧澤欠橘,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站现恼,受9級(jí)特大地震影響肃续,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜叉袍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一始锚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧喳逛,春花似錦瞧捌、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至转唉,卻和暖如春皮钠,著一層夾襖步出監(jiān)牢的瞬間稳捆,已是汗流浹背赠法。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砖织。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓款侵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親侧纯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子新锈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

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