目錄
1. 前言
2.訊號量
3.訊號量集結構
4.建立訊號量semget
5.改變訊號量值semop
6.控制訊號量semctrl
本文章中所有例子,基於rhel6.5。
訊號量是一種用於提供不同程序間或乙個程序間的不同執行緒間進行同步手段的原語,system v訊號量在核心中維護。
二值訊號量:其值只有0、1 兩種選擇,0表示資源被鎖,1表示資源可用;
計數訊號量:其值在0 和某個限定值之間,不限定資源數隻在0 1 之間;
計數訊號量集:多個訊號量的集合組成訊號量集。
核心維護的訊號量集結構資訊如下:
定義在標頭檔案
struct semid_ds ;
其中ipc_perm 結構是核心給每個程序間通訊物件維護的乙個資訊結構,其成員包含所有者使用者id,所有者組id、建立者及其組id,以及訪問模式等;
semid_ds結構體中的sem結構是核心用於維護某個給定訊號量的一組值的內部結構,其結構定義:
struct sem ;
求訊號量極值
# sysctl -a | grep sem
輸出格式分別是:
semmsl(每個訊號量集最大訊號量數目)
semmns(整個系統可以建立的訊號量最大數目)
semopm(每次semop對訊號量操作的最大值)
semmni(系統中可以建立的訊號量集中的最大數目)
int semget(key_t key, int nsems, int sem***); //成功返回訊號量標示符,失敗返回-1
key:是通過呼叫ftok函式得到的鍵值;
nsems:代表建立訊號量的個數,如果只是訪問而不建立則可以指定該引數為0,我們一旦建立了該訊號量,就不能更改其訊號量個數,只要你不刪除該訊號量,你就是重新呼叫該函式建立該鍵值的訊號量,該函式只是返回以前建立的值,不會重新建立;
sem***:指定該訊號量的讀寫許可權,當建立訊號量時不許加ipc_creat ,若指定ipc_creat | ipc_excl則建立是存在該訊號量,建立失敗;
#include #include #include #include int main()
//建立包含訊號量的訊號集,許可權666,訊號量集中的訊號量數目是1個
if ((semid = semget(semkey, 1, ipc_creat | 0666)) < 0)
printf("semid=%d\n", semid);
return 0;
}
執行結果:
訊號量操作是pv操作,「互斥」與「同步」
int semop(int semid, struct sembuf *sops, unsigned nsops); //成功返回0,失敗返回-1;
第乙個引數semid 為訊號量標示符;nsops為第二個引數的運算元組的個數,第二個引數sops為乙個結構體陣列指標,結構體定義在sys/sem.h中,結構體如下:
struct sembuf ;
sem_op取值 >0 則訊號量加上它的值,等價於程序釋放訊號量控制的資源
sem_op取值 =0若沒有設定ipc_nowait, 那麼呼叫程序 將進入睡眠狀態,直到訊號量的值為0,否則程序直接返回
sem_op取值 <0則訊號量加上它的值,等價於程序申請訊號量控制的資源,若程序設定ipc_nowait則程序再沒有可用資源情況下,程序阻塞,否則直接返回。
int semctl(int semid, int semnum, int cmd, ...); // 成功返回非負值,失敗返回-1
semid:訊號集的識別符號;
semnum:標識乙個特定訊號,該引數僅用於 setval、getval、getpid命令;
cmd控制型別;
...說明函式引數是可選的,通過該共用體變數semun選擇操作引數,各欄位如下:
union semun ;
其中,seminfo的定義如下:
struct seminfo ;
semctl的cmd引數
--ipc_stat讀取乙個訊號量集的資料結構semid_ds,並將其儲存在semun中的buf引數中。
--ipc_set設定訊號量集的資料結構semid_ds中的元素ipc_perm,其值取自semun中的buf引數。
--ipc_rmid將訊號量集從系統中刪除
--getall用於讀取訊號量集中的所有訊號量的值,存於semnu的array中
--setall設定所指定的訊號量集的每個成員semval的值
--getpid返回最後乙個執行semop操作的程序的pid。
--lsetval把的val資料成員設定為當前資源數
--getval把semval中的當前值作為函式的返回,即現有的資源數,返回值為非負數
#include #include #include #include #include typedef union semun//semctl需要的
semctl_union;
int main()
if ((semid = semget(semkey, 1, 0)) < 0)//建立訊號量
semctl_arg.val = 2;//初始化
if (semctl(semid, 0, setval, semctl_arg) < 0)//設定訊號量初始值
memset(&buf, 0x00, sizeof(struct sembuf));//清空
buf.sem_num = 0;//訊號量序號從0開始,第乙個
buf.sem_op = -1;//p操作,所以-1
buf.sem_*** = ipc_nowait;//非阻塞
for (n = 0;; n++)//迴圈呼叫p操作,直到訊號量變為0
printf("semop[%d]:current semphore value=%d\n", n, semctl(semid, 0, getval, semctl_arg));
}return 0;
}
執行結果: 程序間通訊 訊號量
ipc識別符號和關鍵字 在終端輸入ipcs,可以看到目前系統中所有的ipc資訊 第一列的key就是ipc的關鍵字,第二列是ipc的識別符號。ftok 函式用於獲得乙個ipc的關鍵字,其函式原型是 key t ftok const char pathname,int proj id 下面是乙個訊號量的...
程序間通訊 訊號量
system ipc中,對於每乙個新建的訊號量 訊息佇列 共享記憶體,都有乙個在整個系統中唯一的識別符號。每個標識也都有唯一對應的關鍵字,關鍵字的資料型別為ket t 在終端輸入命令 ipcs 可以看到目前系統中所有的ipc資訊 共享記憶體段 鍵 shmid 擁有者 許可權 位元組 nattch 狀...
程序間通訊 訊號量
訊號量不是ipc 機構,它只是乙個計數器用於不同程序之間或同一程序不同執行緒之間的同步,型別 二元訊號 值為0或 1,1說明有可用資源,0說明此時資源占用,其他程序需等待。計數訊號量 表示可用資源數量。計數訊號量集 由乙個或多個訊號量組成的集合,每乙個都是計數訊號量。訊號量資料結構 include ...