訊號量和互斥鎖(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,是負責協調各個執行緒,以保證它們能夠正確 合理的使用公共資源。也是作業系統中用於控制程序同步互斥的量。或者說,簡單的來講,就 是訊號量。比如我們去網咖開機子上網 原諒樓主是個網癮...