semaphore

前言

信號量的概念是狄克斯特拉提出的包吝,他定義了PV原語,P操作即等待通過(wait)腹纳,V操作表示釋放(post)痢掠,之所以叫做P,V驱犹,是因為狄克斯特拉是用荷蘭文定義的,P是passeren足画,V是vrijgeven雄驹;

本文重點描述了POSIX標準下的信號量使用。
信號量本質上是一個計數(shù)器淹辞,表征資源可用數(shù)量医舆。大于0時資源可訪問,小于等于0時象缀,資源不可訪問蔬将,線程只能等待;

sem_t

定義在semaphore.h頭文件中央星,其定義如下:

typedef struct {
  unsigned int count;
#ifdef __LP64__
  int __reserved[3];
#endif
} sem_t;

由以上代碼可見霞怀,sem_t是一個struct,在32bit程序中莉给,內(nèi)部只有一個unsigned int數(shù)據(jù)count毙石。

sem_t相關的操作如下:

int sem_destroy(sem_t* __sem);
int sem_getvalue(sem_t* __sem, int* __value);
int sem_init(sem_t* __sem, int __shared, unsigned int __value);
int sem_post(sem_t* __sem);
int sem_timedwait(sem_t* __sem, const struct timespec* __ts);
int sem_trywait(sem_t* __sem);
int sem_wait(sem_t* __sem);

sem_init

這個函數(shù)在Mac OSX下標記為deprecated,在mac下應當使用sem_open();
初始化信號量颓遏,包含3個參數(shù)徐矩,分別是信號量指針,共享模式州泊,value初始值丧蘸,分別解釋下:

  • __sem: 要初始化的信號量指針
  • __shared: 若為0,表示進程內(nèi)私有遥皂,只能進程內(nèi)多線程共享,若不為0刽漂,表示可以進程間共享(有說法不為0可能造成函數(shù)調(diào)用失敗演训,屬于無名信號量,待驗證)
  • __value: 信號量的初值

sem_wait

阻塞當前線程贝咙,直到信號量的值大于0样悟,接觸阻塞后將信號量的值減1,表示公共資源使用后減少庭猩;
是一個原子操作窟她;

sem_post

該線程會釋放資源,使信號量的值加1蔼水;當有某個線程等待這個信號量時震糖,該線程即可以運行,并且將將信號量的值減1(參見sem_wait)趴腋;

sem_destroy

銷毀信號量, 這個函數(shù)在Mac OSX下標記為deprecated吊说,在mac下應當使用sem_close();

注意

在Mac OSX中论咏,創(chuàng)建信號量和銷毀信號量應當用sem_open和sem_close;并且創(chuàng)建的是有名信號量颁井,即信號量以文件的方式存在厅贪,可以跨進程調(diào)用。

sem_open

sem_t * sem_open(const char *, int, ...);

sem_close

int sem_close(sem_t *);

sem_unlink

int sem_unlink(const char *);

sem_unlink的作用是刪除已存在的信號量雅宾,注意有名信號量在程序結束后可能依然存在养涮,所以需要調(diào)用sem_unlink手動刪除;

舉一個??

在以下例子中眉抬,子線程作為數(shù)據(jù)生產(chǎn)者单寂,會更新num;而主線程則作為數(shù)據(jù)消費者吐辙,讀取num宣决;

#include <semaphore.h>
#include <thread>
#include <iostream>

int main(int argc, char** argv) {
    // initialize semaphore
    sem_unlink("sem_num");
    sem_t* m_sem = sem_open("sem_num", O_CREAT|O_EXCL, S_IRWXU, 0);

    int num = 0;

    std::thread write_th([&]() -> void {
        for(size_t i = 0; i < 100000; ++i) {
            num += 1;
        }
        std::cout << "from write th, num is: " << num << std::endl;
        sem_post(m_sem);
    });

    sem_wait(m_sem);
    std::cout << "from read th, num is: " << num << std::endl;
    
    sem_close(m_sem);

    write_th.join();

    return 0;
}

一些思考

1)當初始化sem_t的初值不為0,如給5昏苏,表示的意義尊沸,及應用場景

能否通過信號量實現(xiàn)一定意義上的線程調(diào)度?比如控制一定數(shù)量的線程運行和阻塞贤惯?可實現(xiàn)線程池(將task隊列作為資源洼专,task的數(shù)量即為信號量的數(shù)值,當線程執(zhí)行一個任務時孵构,需要wait信號量屁商,即若有任務,則執(zhí)行颈墅,并將信號量減1蜡镶,否則阻塞等待)

2)semaphore與condition variable有類似之處,兩種異同

3)信號量是否適合一個生產(chǎn)者多個消費者的場景恤筛?
我的觀點是信號量不太適合官还,雖然也可以做(方法是將消費者看做資源,消費者數(shù)量為信號量數(shù)值毒坛,通知了一個消費者望伦,則將信號量減1,否則等待消費者煎殷,優(yōu)點別扭)屯伞;這種場合更適合用條件變量去做;

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末豪直,一起剝皮案震驚了整個濱河市劣摇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌顶伞,老刑警劉巖饵撑,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剑梳,死亡現(xiàn)場離奇詭異,居然都是意外死亡滑潘,警方通過查閱死者的電腦和手機垢乙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來语卤,“玉大人追逮,你說我怎么就攤上這事〈舛妫” “怎么了钮孵?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長眼滤。 經(jīng)常有香客問我巴席,道長,這世上最難降的妖魔是什么诅需? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任漾唉,我火速辦了婚禮,結果婚禮上堰塌,老公的妹妹穿的比我還像新娘赵刑。我一直安慰自己,他們只是感情好场刑,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布般此。 她就那樣靜靜地躺著,像睡著了一般牵现。 火紅的嫁衣襯著肌膚如雪铐懊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天施籍,我揣著相機與錄音居扒,去河邊找鬼。 笑死丑慎,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的瓤摧。 我是一名探鬼主播竿裂,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼照弥!你這毒婦竟也來了腻异?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤这揣,失蹤者是張志新(化名)和其女友劉穎悔常,沒想到半個月后影斑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡机打,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年矫户,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片残邀。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡皆辽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出芥挣,到底是詐尸還是另有隱情驱闷,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布空免,位于F島的核電站空另,受9級特大地震影響,放射性物質發(fā)生泄漏蹋砚。R本人自食惡果不足惜扼菠,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望都弹。 院中可真熱鬧娇豫,春花似錦、人聲如沸畅厢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽框杜。三九已至浦楣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咪辱,已是汗流浹背振劳。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留油狂,地道東北人历恐。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像专筷,于是被迫代替她去往敵國和親弱贼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

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