標籤:linux 網路編程 訊號量
sem_init的應用(1)訊號量用sem_init函數建立的,下面是它的說明:#include<semaphore.h>int sem_init (sem_t *sem, int pshared, unsigned int value);這個函數的作用是對由sem指定的訊號量進行初始化,設定好它的共用選項,並指定一個整數類型的初始值。pshared參數控制著訊號量的類型。
如果 pshared的值是0,就表示它是當前進程的局部訊號量或者說為
線程的共用訊號量;否則,其它進程就能夠共用這個訊號量。value的值為訊號量的初始值(2)這兩個函數控制著訊號量的值,它們的定義如下所示:#include <semaphore.h>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的非阻塞搭檔。sem_trywait是一個立即返回函數,不會因為任何事情阻塞。根據其返回值得到不同的資訊。如果返回值為0,說明訊號量在該函數調用之前大於0,但是調用之後會被該函數自動減1,至於調用之後是否為零則不得而知了。如果返回值為EAGAIN說明訊號量計數為0。(3) 獲得訊號量sem的值,並儲存到valp中。下面的定義:#include<semaphore.h>int sem_getvalue(sem_t *sem, int *valp);(4) 最後一個訊號量函數是sem_destroy。這個函數的作用是在我們用完訊號量對它進行清理。下面的定義:#include<semaphore.h>int sem_destroy (sem_t *sem);這個函數也使用一個訊號量指標做參數,歸還自己佔據的一切資源。在清理訊號量的時候如果還有線程在等待它,使用者就會收到一個錯誤。然而在linux的線程中,其實是沒有任何資源關聯到訊號量對象需要釋放的,因此在linux中,銷毀訊號量對象的作用僅僅是測試是否有線程因為該訊號量在等待。如果函數返回0說明沒有,正常登出訊號量,如果返回EBUSY,說明還有線程正在等待該訊號量的訊號。與其它的函數一樣,這些函數在成功時都返回“0”。
Linux訊號量