操作系統(tǒng)知識(shí)點(diǎn)(七)——信號(hào)量

信號(hào)量

背景

信號(hào)量(semaphore)

  • 抽象數(shù)據(jù)類型

    • 一個(gè)整形(sem),兩個(gè)原子操作

    • P():sem減1避凝,如果sem<0社痛,等待,否則繼續(xù)

    • V():sem加1水醋,如果sem<=0旗笔,喚醒一個(gè)等待的P

信號(hào)量使用

特性
  • 信號(hào)量是被保護(hù)的整數(shù)變量

    • 初始化完成后,只能通過P()和V()操作修改

    • 由操作系統(tǒng)保證拄踪,PV操作是原子操作

  • P()可能阻塞蝇恶,V()不會(huì)阻塞

  • 通常假定信號(hào)量是”公平的“

    • 線程不會(huì)被無限期阻塞在P()操作

    • 假定信號(hào)量等待按先進(jìn)先出排隊(duì)

分類
  • 二進(jìn)制信號(hào)量:可以是0或1

  • 一般/計(jì)數(shù)(資源)信號(hào)量:可取任何非負(fù)值

  • 兩者等價(jià):基于一個(gè)可以實(shí)現(xiàn)另一個(gè)

使用
  • 互斥訪問:臨界區(qū)的互斥訪問控制

  • 條件同步:線程間的事件等待

生產(chǎn)者-消費(fèi)者問題
  • 生成者->緩沖區(qū)->消費(fèi)者

  • 有界緩沖區(qū)的生產(chǎn)者-消費(fèi)者問題描述

    • 一個(gè)或多個(gè)生產(chǎn)者在生成數(shù)據(jù)后放在一個(gè)緩沖區(qū)里

    • 單個(gè)消費(fèi)者從緩沖區(qū)取出數(shù)據(jù)處理

    • 任何時(shí)刻只能有一個(gè)生產(chǎn)者或消費(fèi)者可訪問緩沖區(qū)

  • 問題分析

    • 任何時(shí)刻只能有一個(gè)線程操作緩沖區(qū)(互斥訪問)

    • 緩沖區(qū)空時(shí),消費(fèi)者必須等待生產(chǎn)者(條件同步)

    • 緩沖區(qū)滿時(shí)惶桐,生產(chǎn)者必須等待消費(fèi)者(條件同步)

  • 用信號(hào)量描述每個(gè)約束

    • 二進(jìn)制信號(hào)量mutex

    • 資源信號(hào)量fullBuffers

    • 資源信號(hào)量emptyBuffers

class BoundedBuffer{
    mutex =new Semaphore(1);
    fullBuffers =new Semaphore(0);
    emptyBuffers =new Semaphore(n);
}
BoundedBuffer::Producter(c){
    emptyBuffers ->P();
    mutex ->P();
    ADD C TO THE BUFFER;
    mutex ->V();
    fullBuffers ->V();
}
BoundedBuffer::Consumer(c){
    fullBuffers ->P();
    mutex ->P();
    REMOVE C FROM BUFFER;
    mutex ->V();
    emptyBuffers ->V();
}

信號(hào)量實(shí)現(xiàn)

  • 實(shí)現(xiàn)
class Semaphore{
    int sem;
    WaitQueue q;
}
Semaphore: P(){
    sem--;
    if(sem<0){
        ADD THIS THREAD t TO q;
        block(q);
    }
}
Semaphore: V(){
    sem++;
    if(sem<=0){
        REMOVE a THREAD t FROM q;
        wakeup(t);
    }
}
  • 困難

    • 讀/開發(fā)代碼比較困難

    • 容易出錯(cuò)撮弧。使用的信號(hào)量已經(jīng)被另一個(gè)線程占用;忘記釋放信號(hào)量

    • 不能夠處理死鎖問題

管程(Moniter)

  • 管程是一種用于多線程互斥訪問共享資源的程序結(jié)構(gòu)

    • 采用面向?qū)ο蠓椒ㄒ?jiǎn)化了線程間的同步控制

    • 任一時(shí)刻最多只有一個(gè)線程執(zhí)行管程代碼

    • 正在管程中的線程可臨時(shí)放棄管程的互斥訪問贿衍,等待事件出現(xiàn)時(shí)恢復(fù)

  • 使用

    • 在對(duì)象/模塊中,收集相關(guān)共享數(shù)據(jù)

    • 定義訪問共享數(shù)據(jù)的方法

  • 組成

    • 一個(gè)鎖:控制管程代碼的互斥訪問

    • 0或者多個(gè)條件變量:管理共享數(shù)據(jù)的并發(fā)訪問

  • 條件變量

    • 條件變量是管程內(nèi)的等待機(jī)制

      • 進(jìn)入管程的線程因資源被搶占而進(jìn)入等待狀態(tài)

      • 每個(gè)條件變量表示一種等待原因救恨,對(duì)應(yīng)一個(gè)等待隊(duì)列

    • wait()操作

      • 將自己阻塞在等待隊(duì)列中

      • 喚醒一個(gè)等待者或釋放管程的互斥訪問

    • signal()操作

      • 將等待隊(duì)列中的一個(gè)線程喚醒

      • 如果等待隊(duì)列為空贸辈,則等同空操作

  • 條件變量實(shí)現(xiàn)

class Condition{
    int numWaiting =0;
    WaitQueue q;
}
Condition::Wait(lock){
    numWaiting++;
    ADD this thread t to q;
    release(lock);
    schedule();
    require(lock);
}
Condition::Signal(){
    if(numWaiting >0){
        REMOVE a thread t from q;
        wakeup(t);
        numWaiting--;
    }
}
  • 管程解決生產(chǎn)者-消費(fèi)者問題
class BoundedBuffer {
    …
    Lock lock;
    int count = 0;
    Condition notFull, notEmpty;
}
BoundedBuffer::Producter(c) {
    lock->Acquire();
    while (count == n)
        notFull.Wait(&lock);
    Add c to the buffer;
    count++;
    notEmpty.Signal();
    lock->Release();
}
BoundedBuffer::Consumer(c) {
    lock->Acquire();
    while (count == 0)    
      notEmpty.Wait(&lock);
    Remove c from buffer;
    count--;
    notFull.Signal();
    lock->Release();
}

經(jīng)典同步問題

讀者-寫者問題
  • 共享數(shù)據(jù)的兩類使用者

    • 讀者:只讀取數(shù)據(jù),不修改

    • 寫者:讀取和修改數(shù)據(jù)

  • 讀者-寫者問題描述:對(duì)共享數(shù)據(jù)的讀寫

    • 讀-讀允許:同一時(shí)刻允許有多個(gè)讀者同時(shí)讀

    • 讀-寫互斥:沒有寫者時(shí)讀者才能讀肠槽,沒有讀者時(shí)寫者才能寫

    • 寫-寫互斥:沒有其它寫者時(shí)才能寫

  • 信號(hào)量方法

class Writer(){
    P(WriteMutex);
    write;
    V(WriteMutex);
}
class Reader(){
    P(CountMutex);
    if(Rcount ==0)
        P(WriteMutex);
    ++Rcount;
    V(CountMutex);
    
    read;
    
    P(CountMutex);
    --Rcount;
    if(Rcount ==0)
        V(WriteMutex);
    V(CountMutex);
}
  • 管程方法
AR = 0;   // # of active readers
AW = 0;   // # of active writers
WR = 0;   // # of waiting readers
WW = 0;   // # of waiting writers
Lock lock;
Condition okToRead;
Condition okToWrite;

//讀者
Private Database::StartRead() {
    lock.Acquire();
    while ((AW+WW) > 0) {
        WR++;
        okToRead.wait(&lock);
        WR--;
    }
    AR++;
    lock.Release();
}
Private Database::DoneRead() {
    lock.Acquire();
    AR--;
    if (AR ==0 && WW > 0) {
        okToWrite.signal();
    }
    lock.Release();
}
Public Database::Read() {
  //Wait until no writers;
  StartRead(); 
  read database;
  //check out – wake up waiting writers; 
  DoneRead(); 
}

//寫者
Private Database::StartRead() {
    lock.Acquire();
    while ((AW+WW) > 0) {
        WR++;
        okToRead.wait(&lock);
        WR--;
    }
    AR++;
    lock.Release();
}
Private Database::DoneRead() {
    lock.Acquire();
    AR--;
    if (AR ==0 && WW > 0) {
        okToWrite.signal();
    }
    lock.Release();
}
Public Database::Read() {
  //Wait until no writers;
  StartRead(); 
  read database;
  //check out – wake up waiting writers; 
  DoneRead(); 
}
哲學(xué)家就餐問題
  • 問題描述

    • 5個(gè)哲學(xué)家圍繞一張圓桌而坐

      • 桌子上放著5支叉子

      • 每?jī)蓚€(gè)哲學(xué)家之間放一支

    • 哲學(xué)家的動(dòng)作包括思考和進(jìn)餐

      • 進(jìn)餐時(shí)需同時(shí)拿到左右兩邊的叉子

      • 思考時(shí)將兩只叉子放回原處

更多精彩擎淤,關(guān)注“咋家”

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市秸仙,隨后出現(xiàn)的幾起案子嘴拢,更是在濱河造成了極大的恐慌,老刑警劉巖筋栋,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炊汤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)抢腐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門姑曙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人迈倍,你說我怎么就攤上這事伤靠。” “怎么了啼染?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵宴合,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我迹鹅,道長(zhǎng)卦洽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任斜棚,我火速辦了婚禮阀蒂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘弟蚀。我一直安慰自己蚤霞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布义钉。 她就那樣靜靜地躺著昧绣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捶闸。 梳的紋絲不亂的頭發(fā)上夜畴,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音鉴嗤,去河邊找鬼斩启。 笑死,一個(gè)胖子當(dāng)著我的面吹牛醉锅,可吹牛的內(nèi)容都是我干的兔簇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼硬耍,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼垄琐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起经柴,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤狸窘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后坯认,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翻擒,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡氓涣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了陋气。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劳吠。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖巩趁,靈堂內(nèi)的尸體忽然破棺而出痒玩,到底是詐尸還是另有隱情,我是刑警寧澤议慰,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布蠢古,位于F島的核電站,受9級(jí)特大地震影響别凹,放射性物質(zhì)發(fā)生泄漏草讶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一番川、第九天 我趴在偏房一處隱蔽的房頂上張望到涂。 院中可真熱鬧,春花似錦颁督、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至昭灵,卻和暖如春吠裆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烂完。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國打工试疙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抠蚣。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓祝旷,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親嘶窄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子怀跛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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

  • 第10章:信號(hào)量與管程 信號(hào)量信號(hào)量使用互斥訪問條件同步管程經(jīng)典同步問題哲學(xué)家就餐問題讀者-寫者問題 10.1 信...
    liuzhangjie閱讀 2,872評(píng)論 0 1
  • 18.1信號(hào)量 回顧 ■并發(fā)問題 多線程并發(fā)導(dǎo)致資源競(jìng)爭(zhēng) ■同步概念 協(xié)調(diào)多線程對(duì)共享數(shù)據(jù)的訪問 任何時(shí)刻只能有一...
    龜龜51閱讀 2,070評(píng)論 0 0
  • 線程同步(互斥鎖與信號(hào)量的作用與區(qū)別) “信號(hào)量用在多線程多任務(wù)同步的,一個(gè)線程完成了某一個(gè)動(dòng)作就通過信號(hào)量告訴別...
    勝浩_ae28閱讀 4,953評(píng)論 0 2
  • 文/白鷺 每年柄冲,我總是特別喜歡九月吻谋,大家都說九月很符合我的氣質(zhì),因?yàn)槲沂蔷旁律南趾幔L(fēng)涼漓拾,白露生阁最,所以給自己取了筆...
    白鷺姑娘閱讀 6,608評(píng)論 127 105
  • 21天E戰(zhàn)到底第一天學(xué)習(xí)打卡,今天是第二次學(xué)習(xí)“認(rèn)識(shí)Excel骇两,突破理論”課程速种,時(shí)隔十天再次學(xué)習(xí)這個(gè)課程又有不同的...
    相信自己_d4c2閱讀 217評(píng)論 0 3