Linux编程常用的函数(四) 信号量

来源:互联网 发布:手机淘宝评价不能晒图 编辑:程序博客网 时间:2024/05/29 08:40

(四) 信号量


1. 内核为每个信号量集合设置了一个semid_ds结构:
  struct demid_ds{
    struct ipc_perm sem_perm;
    unsigned short sem_nsems; //信号量的个数
    time_t sem_otime; //上一次semop的时间
    time_t sem_ctime;//上一次change的时间
    。
 。
 };
2#include<sys/sem.h>. int semget(key_t key, int nsems, int flag);//创建信号量
成功返回一个对应于信号量集标识符的非负整数,不成功返回-1并设置errno,错误码:
EACCES   存在key的信号量,但没有授予权限
EEXIST   存在key的信号量,但是
    ( (semflg & IPC_CREATE) && (semflg & IPC_EXCL) ) != 0
EINVAL   nsems <= 0或者大于系统的限制,或者nsems与信号量集的大小不符
ENOENT   不存在key的信号量,而且(semflg & IPC_CTEATE) == 0
ENOSPC   要超出系统范围内对信号量的限制了
功能:
函数返回与参数key相关的信号量集标识符。
如果键值为IPC_PRIVATE,或者semflg&IPC_CREAT非零且没有信号量集或标识符关联于key,那么函数就创建标识符及与之相关的信号量集。
参数nsems指定了集合中信号量元素的个数,可用0到nsems-1的整数来引用信号量集合中的单个信号量元素。
参数semflg指定信号量集的优先级,权限的设置与文件权限设置相同,并可以通过semclt来修改权限值,在使用信号量元素之前,应该用semctl对其进行初始化。
注意:
函数如果试图创建一个已经存在的信号量集,如果semflg值中包含了IPC_CREAT和IPC_EXCL,则失败并设置errno为EEXIST;否则返回一个已经存在的信号量集的句柄。
3.int semctl(int semid, int semnum, int cmd, …);//信号量控制
如果成功返回一个非负的值,具体返回值取决于cmd的值。
cmd值GETVAL、GETPID、GETNCNT和GETZCNT使semctl返回与cmd相关的值。
如果成功,所有其它的cmd返回0。
如果不成功semctl返回-1并设置errno,必须检测的错误码:
EACCES   对调用程序来说,操作被否定
EINVAL   semid的值或cmd的值无效,或者semnum的值为负或者太大
EPERM   cmd的值为IPC_RMID或IPC_SET,且调用程序没有所要求的特权
ERANGE cmd为SETVAL或SETALL,而且要设置的值越界了
功能:
函数semctl为信号量集semid的semnum个元素提供了控制操作。参数cmd指定了操作类型,第四个参数arg可选,是否使用取决于cmd的值。
cmd的值:
GETALL   在arg.array中返回信号量集的值
GETVAL   返回一个特定信号量元素的值
GETPID   返回最后一个操纵元素的进程的进程ID
GETNCNT   返回等待元素增加的进程的个数
GETZCNT   返回等待元素变成零的进程的个数
IPC_RMID   删除semid标识的信号量集
IPC_SET   设置来之arg.buf的信号量集的权限
IPC_STAT   将信号量集semid的semid_ds结构成员拷贝到arg.buf中
SETALL   用arg.array来设置信号量集的值
SETVAL   将一个特定的信号量元素的值设定为arg.val
其中有几个命令需要一个arg参数来读取或存储结构
参数arg的类型为union semun,必须要定义这个类型的数据:
union semum
{
int       val
struct semid_ds   *buf;
unsigned short   *array;
}arg;
4. int semop(int semid, struct sembuf *sops, size_t nsops);//信号量的操作
成功返回0,不成功返回-1并设置errno,必须检测的错误码:
E2BIG   nsops的值太大
EACCES 对调用程序来说,操作被否定
EAGAIN 操作会阻塞进程但是(sem_flg&IPC_NOWAIT)!= 0
EFBIG   某一个sops条目的sem_num值小于0,或大于信号量集中元素的数目
EIDRM   信号量集标识符semid已经从系统中删除了
EINTR   semop被信号中断
EINVAL   semid的值无效,或者请求做SEM_UNDO操作的独立信号量集的数量
超出了限制
ENOSPC 已经超出了对请求SEM_UNDO的进程数的限制
ERANGE 操作会造成semval或semadj值得溢出
功能:
semop函数在单个信号量集上原子的执行sops数组中指定的所有操作。如果其中任何一个单独的元素操作会使进程阻塞,进程就会阻塞而不会执行任何操作。
说明:
结构struct sembuf指定了一个信号量元素操作,包含下列成员。
short sem_num   信号量元素的数量(信号量元素在信号量集中的序号)
short sem_op   要执行的特定元素操作
short sem_flg   为操作指定选项的标志符
sem_op如果是大于零的整数,semop就将这个值与sem_num号信号量元素相加,并唤醒所有等待该元素增加的进程。
  如果为零,且信号量元素值不为0,semop就会阻塞调用进程(进程在等待0),并增加等待那个信号量元素值变为零的进程计数。
  如果sem_op为负数,那么,如果结果不能为负的话,semop就将sem_op值添加到相应的信号量元素值上去。如果操作可能会使元素值为负,semop就将进程阻塞在使信号量元素值增加的事件上。如果结果值为0,那么semop就唤醒等待0的进程。 

原创粉丝点击