Linux執行緒同步(二)之使用訊號量

2021-08-09 06:17:10 字數 2400 閱讀 2546

1、訊號量是乙個特殊型別的變數,它可以被增加或減少,但對其的關鍵訪問被保證是原子操作,即使在乙個多執行緒程式中也是如此。這意味著如果乙個程式中有兩個(或更多)的執行緒試圖改變乙個訊號量的值,系統將保證所有的操作都將依次進行。但如果是普通變數,來自同一程式中不同執行緒的衝突操作所導致的結果將是不確定的。

2、最簡單的訊號量是二進位制訊號量,它只有0和1兩種取值。還有更通用的訊號量——計數訊號量,它可以有更大的取值範圍。訊號量一般常用來保護一段**,使其每次只能被乙個執行執行緒執行,要完成這個工作,就要使用二進位制訊號量。有時,我們希望可以允許有限數目的執行緒執行一段指定的**,這就需要計數訊號量。

訊號量函式的名字都以sem_開頭,訊號量型別是sem_t,執行緒中使用的基本訊號量函式有4個。分別是:

1、訊號量建立函式

#include 

int sem_init(sem_t *sem,int pshared,usigned int

value);

這個函式初始化sem指向的訊號量物件,設定它的共享選項,並給它乙個初始化的整數值。pshared引數控制訊號量的型別,如果其值為0,就表示這個訊號量是當前程序的區域性訊號量,否則,這個訊號量就可以在多個程序之間共享。(linux還不支援這種共享,給pshared引數傳遞乙個非零值將導致呼叫失敗???)

2、訊號量控制函式

#include 

int sem_wait(sem_t *sem);//相當於p操作

int sem_trywait(sem_t *sem);//sem_wait的非阻塞版本

int sem_post(sem_t *sem);//相當於v操作

(1)sem_post函式的作用是以原子操作方式給訊號量加1.所謂原子操作是指,如果兩個執行緒企圖同時給乙個訊號量加1,它們之間不會互相干擾,而不像如果兩個程式同時對同乙個檔案進行讀取、增加、寫入操作時可能會引起衝突。訊號量的值總是會被正確加2,因為有兩個執行緒試圖改變它。

(2)sem_wait函式以原子操作的方式將訊號量的值減1,但它會等待直到訊號量有個非零值才會開始減法操作。因此,如果對值為2的訊號量呼叫sem_wait,執行緒將繼續進行,但訊號量的值會減到1.如果對值為0的訊號量呼叫sem_wait,這個函式就會等待,直到有其他執行緒增加了該訊號量的值使其不再是0為止。如果兩個執行緒同時在sem_wait呼叫上等待同乙個訊號量變為非零值,那麼當該訊號量被第三個執行緒增加1時,只有其中乙個等待執行緒將開始對訊號量減1,然後繼續執行,另外乙個執行緒還將繼續等待。

(3)sem_trywait函式是sem_wait的非阻塞版本,sem_trywait()函式僅在訊號量當前沒有鎖定的情況下(也就是說,如果訊號量值是正的。),鎖定由sem所引用的訊號量;否則,它就不能鎖定訊號量。

如果呼叫程序成功地執行了由sem指定的訊號量鎖操作,那麼sem_trywait()和sem_wait()函式將返回零。如果呼叫不成功,訊號量的狀態將保持不變,函式將返回-1的值,並設定errno來指示錯誤。

3、訊號量清理函式

#include 

int sem_destroy(sem_t *sem);

與前幾個函式一樣,這個函式也以乙個訊號量指標為引數,並清理該訊號量擁有的所有資源。如果企圖清理的訊號量正在被一些執行緒等待,就會收到乙個錯誤。函式在成功時會返回0。

例1:主線程負責接收使用者輸入,函式執行緒統計使用者輸入的字元個數。(用訊號量實現)

#include 

#include

#include

#include

#include

#include

#include

char buf[128] = ;

sem_t sem;

//函式執行緒

void * fun_pthread1(void *arg)

int count = 0;

while(1)

count++;

}printf("count:%d\n",count);

sem_post(&sem);

sleep(1);

}}//主線程

void main()

sleep(1);

sem_wait(&sem);

}pthread_join(id,null);

sem_destroy(&sem);

pthread_exit(null);

}

執行結果:

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...