1. 什麼是訊號量
linux sem 訊號量是一種特殊的變數,訪問具有原子性, 用於解決程序或執行緒間共享資源引發的同步問題。
使用者態程序對 sem 訊號量可以有以下兩種操作:
等待訊號量
當訊號量值為 0 時,程式等待;當訊號量值大於 0 時,訊號量減 1,程式繼續執行。
傳送訊號量
將訊號量值加 1
通過對訊號量的控制,從而實現共享資源的順序訪問。
2. 相關函式說明
linux 訊號量相關函式都宣告標頭檔案 semaphore.h 標頭檔案中,所以使用訊號量之前需要先包含標頭檔案
#include
訊號量的建立就像宣告一般的變數一樣簡單,例如:sem_t sem,之後對該訊號量進行初始化和使用。
2.1 sem_init
該函式用於建立訊號量,其原型如下:
int sem_init(sem_t *sem, int pshared, unsigned int value);
該函式初始化由 sem 指向的訊號物件,並給它乙個初始的整數值 value。
pshared 控制訊號量的型別,值為 0 代表該訊號量用於多執行緒間的同步,值如果大於 0 表示可以共享,用於多個相關程序間的同步
引數 pshared > 0 時指定了 sem 處於共享記憶體區域,所以可以在程序間共享該變數
2.2 sem_wait
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
sem_wait 是乙個阻塞的函式,測試所指定訊號量的值,它的操作是原子的。若 sem value > 0,則該訊號量值減去 1 並立即返回。若sem value = 0,則阻塞直到 sem value > 0,此時立即減去 1,然後返回。
sem_trywait 函式是非阻塞的函式,它會嘗試獲取獲取 sem value 值,如果 sem value = 0,不是阻塞住,而是直接返回乙個錯誤 eagain。
2.3 sem_post
把指定的訊號量 sem 的值加 1,喚醒正在等待該訊號量的任意執行緒。
int sem_post(sem_t *sem);
2.4 sem_getvalue
int sem_getvalue(sem_t *sem, int *sval);
獲取訊號量 sem 的當前值,把該值儲存在 sval,若有 1 個或者多個執行緒正在呼叫 sem_wait 阻塞在該訊號量上,該函式返回阻塞在該訊號量上程序或執行緒個數。
2.5 sem_destroy
該函式用於對用完的訊號量的清理。它的原型如下:
int sem_destroy(sem_t *sem);
成功則返回 0,失敗返回 -1
3. 乙個訊號量同步執行緒的例子
下面以乙個簡單的多執行緒例子說明如何使用訊號量進行執行緒同步。
在主線程中,建立乙個子執行緒用於處理 resource 共享資源,如果主線程有需求(sem_post),就往其後追加乙個 『a』 字串。
#include
#include
#include
#include
sem_t sem;
void* change_resource(void *res)
}int main()
ret = pthread_create(&thread, null, change_resource, (void*)resource);
if (ret != 0)
while (1)
}資源處理列印如下:
resource changed with value: a
resource changed with value: aa
resource changed with value: aaa
...
Linux 執行緒同步之訊號量同步
linux中兩種基本的同步方法是訊號量和互斥量。這兩種方法很相似,而且它們可以相互通過對方來實現。下面介紹用訊號量進行同步。訊號量概念由荷蘭科學家dijkstra首先提出。訊號量是乙個特殊型別的變數,它可以被增加或者減少。但對其的關鍵訪問被保證是原子操作,即使在乙個多執行緒程式中也是如此。訊號量有兩...
Linux 執行緒同步之訊號量同步
linux中兩種基本的同步方法是訊號量和互斥量。這兩種方法很相似,而且它們可以相互通過對方來實現。下面介紹用訊號量進行同步。訊號量概念由荷蘭科學家dijkstra首先提出。訊號量是乙個特殊型別的變數,它可以被增加或者減少。但對其的關鍵訪問被保證是原子操作,即使在乙個多執行緒程式中也是如此。訊號量有兩...
Linux執行緒同步之訊號量
訊號量可以同時訪問多份資源。include intsem init sem t sem,int pshared,unsigned int value int sem destroy sem t sem int sem post sem t sem int sem wait sem t sem int...