執行緒與訊號量

2021-05-25 06:54:06 字數 2808 閱讀 1726

訊號量的資料型別為結構sem_t,它本質上是乙個長整型的數。

------函式sem_init()用來初始化乙個訊號量。

它的原型為: extern int sem_init __p ((sem_t *__sem, int __pshared, unsigned int __value));

sem為指向訊號量結構的乙個指標;pshared不為0時此訊號量在程序間共享,否則只能為當前程序的所有執行緒共享;value給出了訊號量的初始值。

-----函式sem_post( sem_t *sem )用來增加訊號量的值。當有執行緒阻塞在這個訊號量上時,呼叫這個函式會使其中的乙個執行緒不在阻塞,選擇機制同樣是由執行緒的排程策略決定的。 

-----函式sem_wait( sem_t *sem )被用來阻塞當前執行緒直到訊號量sem的值大於0,解除阻塞後將sem的值減一,表明公共資源經使用後減少。

-----函式sem_trywait ( sem_t *sem )是函式sem_wait()的非阻塞版本,它直接將訊號量sem的值減一。

-----函式sem_destroy(sem_t *sem)用來釋放訊號量sem。

(1)訊號量用sem_init函式建立的,下面是它的說明:

#include

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

這個函式的作用是對由sem指定的訊號量進行初始化,設定好它的共享選項,並指定乙個整數型別的初始值。pshared引數控制著訊號量的型別。如果 pshared的值是0,就表示它是當前里程的區域性訊號量;否則,其它程序就能夠共享這個訊號量。我們現在只對不讓程序共享的訊號量感興趣。 (這個引數受版本影響), pshared傳遞乙個非零將會使函式呼叫失敗。

(2)這兩個函式控制著訊號量的值,它們的定義如下所示:

#include

int sem_wait(sem_t * sem);

int sem_post(sem_t * sem);

這兩個函式都要用乙個由sem_init呼叫初始化的訊號量物件的指標做引數。

sem_post函式的作用是給訊號量的值加上乙個「1」,它是乙個「原子操作"即同時對同乙個訊號量做加「1」操作的兩個執行緒是不會衝突的;而同時對同乙個檔案進行讀、加和寫操作的兩個程式就有可能會引起衝突。訊號量的值永遠會正確地加乙個「2」--因為有兩個執行緒試圖改變它。

sem_wait函式也是乙個原子操作,它的作用是從訊號量的值減去乙個「1」,但它永遠會先等待該訊號量為乙個非零值才開始做減法。也就是說,如果你對乙個值為2的訊號量呼叫sem_wait(),執行緒將會繼續執行,訊號量的值將減到1。如果對乙個值為0的訊號量呼叫sem_wait(),這個函式就會地等待直到有其它執行緒增加了這個值使它不再是0為止。如果有兩個執行緒都在sem_wait()中等待同乙個訊號量變成非零值,那麼當它被第三個執行緒增加乙個「1」時,等待執行緒中只有乙個能夠對訊號量做減法並繼續執行,另乙個還將處於等待狀態。

訊號量這種「只用乙個函式就能原子化地測試和設定」的能力下正是它的價值所在。還有另外乙個訊號量函式sem_trywait,它是sem_wait的非阻塞搭檔。

(3)最後乙個訊號量函式是sem_destroy。這個函式的作用是在我們用完訊號量對它進行清理。下面的定義:

#include

int sem_destroy (sem_t *sem);

這個函式也使用乙個訊號量指標做引數,歸還自己佔據的一切資源。在清理訊號量的時候如果還有執行緒在等待它,使用者就會收到乙個錯誤。

與其它的函式一樣,這些函式在成功時都返回「0」。

程式舉例如下:

#include

#include

#include

#include //包含執行緒相關標頭檔案

#include

#include

#include //包含訊號量相關標頭檔案

int lock_var;

time_t end_time;

sem_t sem1,sem2; //宣告兩個訊號量

void pthread1(void *arg); //宣告兩個執行緒函式

void pthread2(void *arg);

int main(int argc, char *argv)

ret=pthread_create(&id1,null,(void *)pthread1, null); //建立執行緒

if(ret!=0)

perror("pthread cread1");

ret=pthread_create(&id2,null,(void *)pthread2, null);

if(ret!=0)

perror("pthread cread2");

pthread_join(id1,null); //用來等待執行緒1的結束

pthread_join(id2,null);//用來等待執行緒2的結束

exit(0);

} void pthread1(void *arg) //執行緒1的執行內容

printf("pthread1:lock_var=%d/n",lock_var);

sem_post(&sem1); //將訊號量sem1的值加1,代表資源增加

sleep(1);

} }

void pthread2(void *arg) }

訊號量的使用如下步驟小結:

1.宣告訊號量sem_t sem1;

2.初始化訊號量sem_init(&sem1,0,1); /

3.sem_post和sem_wait函式配合使用來達到執行緒同步

4.釋放訊號量int sem_destroy (sem_t *sem1);

執行緒與訊號量

file1 file1實現了1個訊號量,對兩個執行緒的同步.include include include pthread t pthid1,pthid2 sem t sem static void fun1 void arg static void fun2 void arg int main i...

執行緒 訊號量

訊號量 訊號量本質上是乙個非負的整數計數器,它被用來控制對公共資源的訪問。當公共資源增加時,呼叫函式sem post 增加訊號量。只有當訊號量值大於 時,才能使用公共資源,使用後,函式sem wait 減少訊號量。函式sem trywait 和函式pthread mutex trylock 起同樣的...

systemV訊號量 與 Posix訊號量

一 函式上的區別 訊號量有兩種實現 傳統的system v訊號量和新的posix訊號量。它們所提供的函式很容易被區分 對於所有system v訊號量函式,在它們的名字裡面沒有下劃線。例如,應該是semget 而不是sem get 然而,所有的的posix訊號量函式都有乙個下劃線。下面列出了它們提供的...