訊號量Semaphore的用法

2021-09-25 17:15:49 字數 1828 閱讀 8389

訊號量和互斥鎖(mutex)的區別:互斥鎖只允許乙個執行緒進入臨界區,而訊號量允許多個執行緒同時進入臨界區。

不多做解釋,要使用訊號量同步,需要包含標頭檔案semaphore.h。

主要用到的函式:

int sem_init(sem_t *sem, int pshared, unsigned int value);

其中sem是要初始化的訊號量,pshared表示此訊號量是在程序間共享還是執行緒間共享,

value是訊號量的初始值。

int sem_destroy(sem_t *sem);,其中sem是要銷毀的訊號量。

只有用sem_init初始化的訊號量才能用sem_destroy銷毀。

int sem_wait(sem_t *sem);等待訊號量,如果訊號量的值大於0,將訊號量的值減1,立即返回。

如果訊號量的值為0,則執行緒阻塞。相當於p操作。成功返回0,失敗返回-1。

int sem_post(sem_t *sem); 釋放訊號量,讓訊號量的值加1。相當於v操作。

int sem_getvalue(sem_t *sem, int *sval);

取回訊號量sem的當前值,把該值儲存到sval中。

1) 返回0

2) 返回阻塞在該訊號量上的程序或執行緒數目

linux採用返回的第一種策略。

如果我們現在有兩個執行緒,分別負責乙份工作的前半段與後半段,也就是說第乙個執行緒會把它處理好的資料,發包給第二個執行緒繼續處理,而兩個執行緒的處理速度有可能不同,這種狀況我們就可以使用旗標(semaphore)的方式來串接。

旗標本身就是乙個計數器,也就是紀錄目前尚未處理的工作數量,我們可以使用sem_wait來判斷是否有尚未處理的工作,當工作數量大於0時,sem_wait就會讓執行緒進入處理,並且把工作數量遞減1,而如果工作數量為0的時候,則會讓執行緒等待,直到有新的工作來臨時,才讓執行緒進入。

另外在產生工作的執行緒中,可以使用sem_post放入新的工作(也就讓將計數器遞增1),這樣就可以將多個執行緒串接起來處理大型的工作流程。

#include #include #include #include sem_t semaphore; // 旗標

int counter = 0;

// 子執行緒函式

void* child()

pthread_exit(null);

}// 主程式

int main(void)

執行結果:

post 2 jobs.

counter = 1

counter = 2

post 3 jobs.

counter = 3

counter = 4

counter = 5

在這個程式中,主線程負責派送工作,工作有時候多、有時候少,而子執行緒則是以每秒處理乙個工作的速度,消化接收到的工作。

旗標在使用前要先以sem_init初始化,其第二個引數是指定是否要讓其他的行程(process)共用旗標,這裡我們是單一行程、多執行緒的程式,所以第二個引數設定為0即可;第三個引數則是設定旗標的初始值

旗標本身只是紀錄工作的數量,並且控制線程的執行,並沒有負責資料的配送,通常我們可以自己實做乙個資料佇列(queue),配合旗標來計算索引,讓子執行緒從佇列中取得資料進行處理。

參考:

訊號量semaphore解析

1 基礎概念 訊號量在建立時須要設定乙個初始值,表示同一時候能夠有幾個任務能夠訪問該訊號量保護的共享資源。初始值為1就變成相互排斥鎖 mutex 即同一時候僅僅能有乙個任務能夠訪問訊號量保護的共享資源。乙個任務要想訪問共享資源,首先必須得到訊號量,獲取訊號量的操作將把訊號量的值減1。若當前訊號量的值...

訊號量的理解Semaphore

訊號量的概念和鎖很像,不過它是一次給你好幾把鎖,這樣就可以實現同時讓 限定個數的程序來獲取某個資源,看下面的 from multiprocessing import process,semaphore import random import time defktv i,sem sem.acquir...

Semaphore初識 java訊號量

朋友在寫 活動的時候,為了控制線程,用到了semaphore類 之前也是沒有用到過,就簡單認識一下它。semaphore,是負責協調各個執行緒,以保證它們能夠正確 合理的使用公共資源。也是作業系統中用於控制程序同步互斥的量。或者說,簡單的來講,就 是訊號量。比如我們去網咖開機子上網 原諒樓主是個網癮...