多線程編程之訊號量
Pthread是 POSIX threads 的簡稱,是POSIX的線程標準。 互斥量用來處理一個共用資源的同步訪問問題,當有多個共用資源時,就需要用到訊號量機制。 訊號量機制用於保證兩個或多個共用資源被線程協調地同步使用,訊號量的值對應當前可用資源的數量。
1.訊號量(samaphore):
訊號量機制通過訊號量的值控制可用資源的數量。線程訪問共用資源前,需要申請擷取一個訊號量,如果訊號量為0,說明當前無可用的資源,線程無法擷取訊號量,則該線程會等待其他資源釋放訊號量(訊號量加1)。如果訊號量不為0,說明當前有可用的資源,此時線程佔用一個資源,對應訊號量減1。 舉例: 停車場有5個停車位,汽車可使用停車位。在這裡5個停車位是共用的資源,汽車是線程。開始訊號量為5,表明此時有5個停車位可用。一輛汽車進入停車場前,先查詢訊號量的值,不為0表明有可用停車位,汽車進入停車場並使用一個停車位,訊號量減1,表明佔用一個停車位,可用數減少。 2.訊號量基本函數: #include <semaphore.h>
初始化訊號量:
int sem_init(sem_t *sem, int pshared, unsigned int val); 該函數第一個參數為訊號量指標,第二個參數為訊號量類型(一般設定為0),第三個為訊號量初始值。第二個參數pshared為0時,該進程內所有線程可用,不為0時不同進程間可用。
訊號量減1:
int sem_wait(sem_t *sem); 該函數申請一個訊號量,當前無可用訊號量則等待,有可用訊號量時佔用一個訊號量,對訊號量的值減1。
訊號量加1:
int sem_post(sem_t *sem); 該函數釋放一個訊號量,訊號量的值加1。
銷毀訊號量:
int sem_destory(sem_t *sem); 該函數銷毀訊號量。
3.牛刀小試: 採用訊號量機制,解決蘋果橙子問題:一個能放N(這裡N設為3)個水果的盤子,爸爸只往盤子裡放蘋果,媽媽只放橙子,女兒只吃盤子裡的橙子,兒子只吃蘋果。 採用三個訊號量: 1.sem_t empty:訊號量empty控制盤子可放水果數,初始為3,因為開始盤子為空白可放水果數為3。 2.sem_t apple ;訊號量apple控制兒子可吃的蘋果數,初始為0,因為開始盤子裡沒蘋果。 3.sem_t orange;訊號量orange控制女兒可吃的橙子是,初始為0,因為開始盤子裡沒橙子。註:互斥量work_mutex只為printf輸出時能夠保持一致,可忽略。