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)

扫描二维码关注公众号,回复: 1110365 查看本文章

获取正在等待某个信号量为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联合体!实际编程时也不需要使用这个联合体类型。



猜你喜欢

转载自blog.csdn.net/zlk1214/article/details/78410959