Linux信号量常用操作表
以下函數失敗時均返回-1,所在頭文件為#include<sys/sem.h>
創建用于區分信號量的鍵值key:key_t key = ftok("/foo/bar/", 'a'),第一個參數為任意路徑,第二個參數為任意8位的字符。如果設定的路徑為當前目錄“.”,則生成的key與控制臺當前所在的目錄(pwd)有關,與程序所在的目錄無關
創建一個信號量集:int sem = semget(key, 信號量集中欲創建的信號量的個數, 權限 | IPC_CREAT) ,失敗時返回-1,權限可以是八進制的0666(mode_t位于頭文件fcntl.h中)。若指定IPC_EXCL(inter-process communication, exclude)選項,則信號量集已存在時會失敗。權限值還可以用一組系統標識符(system identifier)來表示,例如0644= 420 = 0x1a4可以表示為S_IRUSR| S_IWUSR | S_IRGRP | S_IROTH,標識符所在的頭文件為<fcntl.h>
[oct1158@oct1158-fedora sem2]$ grep S_IRGRP -Inrw /usr/include /usr/include/fcntl.h:111:# define S_IRGRP (S_IRUSR >> 3) /* Read by group. */ /usr/include/fcntl.h:117:# define S_IROTH (S_IRGRP >> 3) /* Read by others. */ /usr/include/sys/stat.h:180:#define S_IRGRP (S_IRUSR >> 3) /* Read by group. */ /usr/include/sys/stat.h:186:#define S_IROTH (S_IRGRP >> 3) /* Read by others. */ /usr/include/sys/stat.h:197:# define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)/* 0666*/ /usr/include/linux/stat.h:35:#define S_IRGRP 00040 [oct1158@oct1158-fedora sem2]$ grep "mode_t;" -Inrw /usr/include /usr/include/fcntl.h:50:typedef __mode_t mode_t; /usr/include/sys/types.h:70:typedef __mode_t mode_t; /usr/include/sys/mman.h:37:typedef __mode_t mode_t; /usr/include/sys/ipc.h:38:typedef __mode_t mode_t; /usr/include/sys/stat.h:59:typedef __mode_t mode_t; [oct1158@oct1158-fedora sem2]$獲取信號量集:int sem = semget(key, 0, 0)
獲取單個信號量的值:semctl(信號量集, 信號量編號, GETVAL),第一個參數就是上面的sem,信號量編號是從0開始的
設置單個信號量的值:semctl(信號量集, 信號量編號, SETVAL, 值)
獲取信號量集中的信號量個數:struct semid_ds ds;??? semctl(信號量集, 0, IPC_STAT, &ds);??? int count = ds.sem_nsems,加粗的參數為無效參數,函數執行時將會被忽略掉
獲取信號量集中所有信號量的值:semctl(信號量集, 0, GETALL, list),其中list的類型為unsigned short *,必須用malloc分配足夠的空間:list= (unsigned short *)malloc(ds.sem_nsems * sizeof(unsigned short)),輸出時printf要用%hd
設置信號量集中所有信號量的值:semctl(信號量集, 0, SETALL, list)
獲取正在等待某個信號量有足夠資源的進程數:semctl(信號量集, 信號量編號, GETNCNT)
獲取正在等待某個信號量為0的進程數:semctl(信號量集, 信號量編號, GETZCNT)
刪除信號量集:semctl(信號量集, 0, IPC_RMID),同時喚醒所有等待的進程
獲取最后一次對某一個信號量執行semop函數的進程號:semctl(信號量集, 信號量編號, GETPID)
?
PV操作函數:
struct sembuf buf;
semop(信號量集,&buf, 1); // 操作單個信號量
struct sembuf buf[4];
semop(信號量集,buf, 4); // 操作4個信號量
參數buf的結構體成員:
buf.sem_num = 0; // 要操作或等待的信號量編號(unsigned short),輸出格式為%hu
buf.sem_op = -10; // 要獲取(負數)或釋放(正數)的資源數,輸出格式為%hd
buf.sem_flg = 0; // 附加參數,輸出格式為0x%04x
當sem_op為負時,若資源數不夠,則會阻塞
當sem_op為0時,且信號量的值不為0時阻塞,直到信號量的值為0
若指明附加參數sem_flg=IPC_NOWAIT,則該阻塞時不阻塞,函數立即返回-1(獲取資源失敗)
若指明附加參數sem_flg=SEM_UNDO,則進程結束時系統自動加回未釋放的資源數。
兩個附加參數可以同時使用:sem_flg= IPC_NOWAIT | SEM_UNDO
?
AND型信號量:
struct sembuf buf[2];
buf[0].sem_ num = 1; buf[0].sem_op = -4; buf[0].sem_flg = 0;
buf[1].sem_num = 2; buf[1].sem_op = -10; buf[1].sem_flg = 0;
semop(sem, buf, 2);
只有當信號量1的值>=4,且信號量2的值>=10,進程才不會阻塞
?
struct sembuf結構體的定義如下:
注意:最新的Linux系統里面沒有union semun聯合體!實際編程時也不需要使用這個聯合體類型。
總結
以上是生活随笔為你收集整理的Linux信号量常用操作表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux强行退出线程,Linux 多线
- 下一篇: 对linux信号量的理解以及实现