程序間同步之訊號量(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 ...