信號量定義及實例講解

信號量

引用:

  • 借鑒自《深入理解計算機系統(tǒng)》

作用:

  • 信號量的一個作用是用來做線程間對貢獻(xiàn)變量的互斥訪問。
  • 信號量的另一個重要作用是調(diào)度對共享資源的訪問。一個線程用信號量操作來通知另一個線程。

實現(xiàn):

  • 信號量是具有非負(fù)整數(shù)值的全局變量,只能由兩種特殊的操作來處理,這兩種操作稱為P和V。
  • P(s):如果s是非零的,那么P將s減一,并且立即返回。如果s為零,那么就掛起這個線程,直到s變?yōu)榉橇?,而一個V操作會重啟這個線程。
  • V(s):V操作將s加1,如果有任何線程阻塞在P操作等待s變?yōu)榉橇?,那么V操作會重啟這些線程中的一個,然后該線程將s減1,完成它的P操作
  • P中的測試和減一操作是不能分割的。V中的加一操作也是不可分割的。
  • P和V的定義確保了一個正在運行的程序絕不可能進(jìn)入這樣一種狀態(tài),也就是一個正確初始化了的信號量有一個負(fù)值。這個屬性成為信號量不變性。
  • 信號量提供了一種很方便的方法來確保對共享變量的互斥訪問。
  • 在一個互斥鎖上執(zhí)行P操作稱為對互斥鎖加鎖,執(zhí)行V操作稱為對互斥鎖解鎖。
  • 對一個互斥鎖加了鎖但是還沒有解鎖的線程稱為占用這個互斥鎖,一個被用作一組可用資源的計數(shù)器的信號量成為計數(shù)信號量。

函數(shù)定義

#include <semaphore.h>
int sem_int(sem_t *sem, unsigned int value);
void P(sem_t *sem) 
{
    if (sem_wait(sem) < 0)
     unix_error("P error");
}
void V(sem_t *sem)
{
    if (sem_post(sem) < 0)
    unix_error("V error");
}

使用信號量解決讀者寫者問題:

描述:
  • 讀者線程只讀取對象
  • 寫者線程修改對象
  • 寫者對于對象的訪問是互斥的
  • 多個讀者可以同時讀取對象
應(yīng)用場景
  • 在線訂票系統(tǒng)(多讀一寫)
  • 多線程緩存 web 代理
第一類讀者寫者問題(讀者優(yōu)先)
  • 如果寫者沒有獲取到使用對象的權(quán)限,不應(yīng)該讓讀者等待
  • 在等待的寫者之后到來的讀者應(yīng)該在寫者之前處理
  • 也就是說,只有沒有讀者的情況下,寫者才能工作
  • 代碼示例:
int readcnt;    /* Initially = 0 */
sem_t mutex, w; /* Both initially = 1 */

void reader(void) 
{
    while (1) {
        P(&mutex);
        readcnt++;
        if (readcnt == 1) /* First in */
            P(&w);          
        V(&mutex);          

        /* Critical section */
        /* Reading happens  */

        P(&mutex);
        readcnt--;
        if (readcnt == 0) /* Last out */
            V(&w);
        V(&mutex);
    }
}
/* $end reader1 */

/* $begin writer1 */
void writer(void) 
{
    while (1) {
        P(&w);

        /* Critical section */
        /* Writing happens  */ 

        V(&w);
    }
}
/* $end writer1 */
第一類讀者寫者問題(寫者優(yōu)先)
  • 一旦寫者可以處理的時候,就不應(yīng)該進(jìn)行等待
  • 在等待的寫者之后到來的讀者應(yīng)該在寫者之后處理
  • 代碼示例:
/* Global variables */
sem_t sem;    /* Initially = N */
sem_t wmutex; /* Initially = 1 */

void reader(void) 
{
    while (1) {
        P(&sem);

        /* Critical section: */
        /* Reading happens   */

        V(&sem);
    }
}

void writer(void) 
{
    int i;

    while (1) {
        P(&wmutex);
        for (i=0; i<N; i++)
            P(&sem);
        V(&wmutex);

        /* Critical section: */
        /* Writing happens   */

        for (i=0; i<N; i++)
            V(&sem);
    }
}
/* $end rw3 */
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.信號量機制 信號量機制即利用pv操作來對信號量進(jìn)行處理。 什么是信號量?信號量(semaphore)的數(shù)據(jù)結(jié)構(gòu)...
    殺手的手剎閱讀 17,045評論 0 5
  • 現(xiàn)代操作系統(tǒng)提供了三種基本的構(gòu)造并發(fā)程序的方法: 1、進(jìn)程: 每個邏輯控制流都是一個進(jìn)程,由內(nèi)核來調(diào)度和維護(hù)。因為...
    ShawnPanCn閱讀 677評論 0 0
  • 第十二章、并發(fā)編程 現(xiàn)代操作系統(tǒng)提供了三種基本的構(gòu)造并發(fā)程序的方法: 1、進(jìn)程: 每個邏輯控制流都是一個進(jìn)程,由內(nèi)...
    wenmingxing閱讀 634評論 0 3
  • 第10章:信號量與管程 信號量信號量使用互斥訪問條件同步管程經(jīng)典同步問題哲學(xué)家就餐問題讀者-寫者問題 10.1 信...
    liuzhangjie閱讀 2,968評論 0 1
  • 2.1進(jìn)程的基本概念 一、程序順序執(zhí)行時的特征 (一)、順序性:處理機的操作嚴(yán)格按程序規(guī)定順序執(zhí)行 (二)、封閉性...
    山隹金易錫閱讀 2,717評論 0 2

友情鏈接更多精彩內(nèi)容