程序間通訊之Posix 訊號量

2021-08-03 04:23:38 字數 3095 閱讀 5230

概述

訊號量(semaphore)是一種用於提供不同程序間或者乙個給定程序的不同執行緒間同步手段的原語。

1.posix 有名訊號量:使用posix ipc 名字標識,可用於程序或執行緒間的同步。

2.posix 基於記憶體的訊號量:存放在共享記憶體區中,可用於程序或執行緒間的同步。

我們暫時只考慮不同程序間的同步。首先考慮二值訊號量(binary semaphore):其值或為0或為1的訊號量。

posix 訊號量不必在核心中維護。另外,posix 訊號量是由可能與檔案系統中的路徑名對應的名字來標識的,但是並不要求它們真正存放在檔案系統內的某個檔案中。

由上圖可看出,程序可以在某個訊號量上執行三種操作:

1.建立乙個訊號量。要求呼叫者指定初始值,對於二值訊號量來說,它通常是1,但也可以是0。

2.等待乙個訊號量。該操作會測試這個訊號量的值,如果其值小於或等於0,那就等待(阻塞),一旦其值變為大於0就將它減1。

3.掛出乙個訊號量。該操作將訊號量的值加1,如果有一些程序阻塞著等待該訊號量的值變為大於0,其中乙個程序就可能被喚醒。

有名訊號量和基於記憶體的訊號量使用函式對比:

函式說明

sem_open、sem_close和sem_unlink函式

1.函式sem_open建立乙個新的有名訊號量或開啟乙個已存在的有名訊號量。有名訊號量總是既可用於執行緒間的同步,又可用於程序間的同步。

sem_t *sem_open(const char *name, int oflag, ... /*mode_t mode, unsigned int value*/);

返回:若成功則為指向訊號量的指標,若出錯則為sem_failed。

name 引數規則:1.必須符合已有的路徑名規則(最多有path_max個字元構成,包括結尾的空字元); 2.名字必須已乙個斜槓符開頭,並且不能函式任何其他斜槓符;

oflag 引數:可以是0、o_creat(若不存在則建立)或ocreat | o_excl(排他性建立)。如果指定了o_creat標誌,那麼第三個和第四個引數是需要的。

mode 引數:指定許可權位 。

value 引數:指定訊號量的初始值。二值訊號量的初始值通常為1,計數訊號量的初始值則往往大於1。

備註:oflag 引數中還可以指定 o_rdonly  o_wronly 或 o_rdwr標誌,但通常呼叫sem_open 預設攜帶o_rdwr標誌。

2.函式sem_close關閉開啟的乙個有名訊號量。

int sem_close(sem_t *sem);

返回:若成功則為0,若出錯則為-1。

乙個程序終止時,核心還對其上仍然開啟著的所有有名訊號量自動執行這樣的訊號量關閉操作。關閉乙個訊號量並沒有將它從系統中刪除,因為posix訊號量是隨核心持續的:即使當前沒有程序開啟著某個訊號量,它的值仍然保持。

有名訊號量使用sem_unlink函式從系統中刪除:

int sem_unlink(const char *name);

返回:若成功則為0,若出錯則為-1。

sem_wait和sem_trywait函式

int sem_wait(sem_t *sem);

int sem_trywait(sem_t *sem);

返回:若成功則為0,若出錯則為-1。

sem_wait函式測試所指定的訊號量的值,如果該值大於0,那就將它減1並立即返回。如果該值等於0,呼叫執行緒就被投入到睡眠中,直到該值變為大於0,這時再將它減1,函式隨後返回。

sem_wait和sem_trywait的差別是:當所指定的訊號量的值已經是0時,後者並不將呼叫執行緒投入睡眠。相反,它返回乙個eagain錯誤。

sem_post和sem_getvalue函式

int sem_post(sem_t *sem);

int sem_getvalue(sem_t *sem, int *valp);

返回:若成功則為0,若出錯則為-1。

當乙個執行緒使用完某個訊號量時,它應該呼叫sem_post。本函式把所指定的訊號量的值加1,然後喚醒正在等待該訊號量值變為正數的任意執行緒。

sem_getvalue在有valp指向的整數中返回所指定訊號量的當前值。如果該訊號量當前已經上鎖,那麼返回或為0,或為某個負數,其絕對值就是等待該訊號量解鎖的執行緒數。

互斥鎖、條件變數和訊號量之間的差別:

首先,互斥鎖必須總是由給它上鎖的執行緒解鎖,訊號量沒有這種限制。其次,既然每個訊號量有乙個與之關聯的值,它由掛出操作加1,由等待操作減1,那麼任何執行緒都可以掛出乙個訊號量,即使當時沒有執行緒等待該訊號量值變為正數也沒有關係。然而,如果某個執行緒呼叫了pthread_cond_signal,不過當時沒有任何執行緒阻塞在pthread_cond_wait呼叫中,那麼發往相應條件變數的訊號將丟失。最後,在各種各樣的同步技巧(互斥鎖、條件變數、讀寫鎖、訊號量)中,能夠從訊號處理程式中安全呼叫的唯一函式就是sem_post。

例子

待補充...

程序間通訊之訊號量

訊號量的本質是一種資料操作鎖,其本身不具有資料交換的能力,而是通過控制其他的通訊資源 檔案 外部裝置 來實現程序間通訊,它本身只是一種外部資源的標識。訊號量在此過程中負責資料的互斥 同步等功能。當請求乙個訊號量來表示資源時,程序需要讀取訊號量的值來判斷資源是否可用。大於0,資源可以請求,等於0,無資...

程序間通訊之訊號量

訊號量的本質是一種資料操控鎖,它本身不具有資料交換的功能,而是通過來控制其他的通訊資源來實現程序間通訊的,訊號主要負責資料的同步與互斥功能。程序請求乙個使用訊號量來表示的資源時,首先要讀取訊號量的值來判斷資源是否能被使用,若訊號量的值大於0,資源可用,等於0,無資源可用,同時程序會進入睡眠狀態,直到...

程序間通訊之 訊號量

訊號量相當於記錄資源能同時被多少個程序訪問。訊號量的作用 程序間同步控制。訊號量有乙個初值,每當有程序申請使用訊號量,就會通過乙個p操作對訊號量進行 1操作,當計數器減到0的時候就說明沒有資源了,其他程序要想訪問就必須等待,當該程序執行完這段工作之後,就會執行v操作,即對訊號量進行 1操作。標頭檔案...