程序間同步之訊號量(semaphore)

2021-08-19 07:27:48 字數 2294 閱讀 7587

程序間同步之訊號量(semaphore)

1. 訊號量的建立與使用

linux下使用semget建立或開啟訊號量集,

int semget(key_t key, int nsems, int sem***);

該函式執行成功則返回乙個訊號量集的識別符號,失敗返回-1。返回的引數key是由ftok得到的鍵值;

第二個引數nsems指明要建立的訊號量集包含的訊號量個數。如果只是開啟訊號量,把nsems設定為0即可。該引數只在建立訊號量集時有效。

第三個引數sem***為操作標識,可取如下值:

0:取訊號量集識別符號,若不存在則函式會報錯

ipc_creat:當sem***&ipc_creat為真時,如果核心中不存在鍵值與key相等的訊號量集,則新建乙個訊號量集;如果存在這樣的訊號量集,返回此訊號量集的識別符號

ipc_creat|ipc_excl:如果核心中不存在鍵值與key相等的訊號量集,則新建乙個訊息佇列;如果存在這樣的訊號量集則報錯

上述sem***引數為模式標誌引數,使用時需要與ipc物件訪問許可權(如0600)進行|運算來確定訊號量集的訪問許可權 2.

訊號量的操作

訊號量的值與相應資源的使用情況有關,當它的值大於0時,表示當前可用資源的數量,當他的值小於0時,其絕對值表示等待

使用這個資源的程序個數。訊號量的值僅能由pv操作來改變。

在linux下,pv操作通過呼叫函式semop實現。該函式定義在標頭檔案sys/sem.h中,原型:

int semop(int semid, struct sembuf *sops, unsigned nsops);

對訊號量集識別符號為semid中的乙個或多個訊號量進行p操作或v操作

semid:訊號量集識別符號

struct sembuf ;

nsops:進行操作訊號量的個數,即sops結構變數的個數,需大於或等於1。最常見設定此值等於1,只完成對乙個訊號量的操作

錯誤**:

e2big:一次對訊號量個數的操作超過了系統限制

eaccess:許可權不夠

eagain:使用了ipc_nowait,但操作不能繼續進行

eidrm:訊號量集已經刪除

sops為指向sembuf陣列,定義所要進行的操作序列。下面是訊號量操作舉例。

struct sembuf sem_get=; /*將訊號量物件中序號為0的訊號量減1*/

struct sembuf sem_get=;  /*將訊號量物件中序號為0的訊號量加1*/

struct sembuf sem_get=;           /*程序被阻塞,直到對應的訊號量值為0*/

flag一般為0,若flag包含ipc_nowait,則該操作為非阻塞操作。若flag包含sem_undo,則當程序退出的時候會還原該程序的訊號量操作,這個標誌在某些情況下是很有用的,

比如某程序做了p操作得到資源,但還沒來得及做v操作時就異常退出了,此時,其他程序就只能都阻塞在p操作上,於是造成了死鎖。若採取sem_undo標誌,就可以避免因為程序異常退出而造成的死鎖。

3. semctl (得到乙個訊號量集識別符號或建立乙個訊號量集物件)

int semctl(int semid, int semnum, int cmd, union semun arg)

semid:訊號量集識別符號

semnum:訊號量集陣列上的下標,表示某乙個訊號量

下面截個圖:

下面舉例說明:

#include #include #include #include #include #include #define number 5

#define key 1111

union semun;

int main()

; struct sembuf sbuf_v = ;

pid_t pid;

sem_id = semget((key_t)key, 1,ipc_creat | 0666);

semattr.val = number;

semctl(sem_id, 0, setval, semattr);

pid = fork();

if(pid == 0)

return 0;

}else

printf("parent process set semaphore\n");

semop(sem_id, &sbuf_v, 1);

} } return 0;

}

程序間同步之訊號量

概念 訊號量是乙個特殊的變數,程式對其訪問都是原子操作,且只允許對它進行等待 即p 訊號變數 和傳送 即v 訊號變數 資訊操作。最簡單的訊號量是只能取0和1的變數,這也是訊號量最常見的一種形式,叫做二進位制訊號量。而可以取多個正整數的訊號量被稱為通用訊號量。二值訊號量 訊號量的值只有0和 1,若資源...

程序間同步 訊號量集

一 建立或者開啟訊號量 int semget key t key,int nsems,訊號量集中訊號量的個數 int flag 開啟 0,建立 ipc creat 0644 返回值 返回訊號量集的識別符號 檢視訊號量 ipcs s 具體案例 include include include inclu...

linux程序間同步之POSIX訊號量

閱讀linux系統程式設計手冊筆記 posix訊號量跟system v訊號量一樣,都是用於程序和執行緒同步對同享資源的訪問。訊號量 posix,system v 是乙個整數,其值是不能小於0的。posix訊號量主要分為 命名訊號量 未命名訊號量。首先先介紹命名訊號量。先來看看命名訊號量的主要api ...