信号量函数

信号量头文件
#include<sys/types>
#include<sys/ipc.h>
#include<sys/sem.h>

semget

执行成功则得到一个信号量集标识符或创建一个信号量集对象,出错返回-1,原因存在errno中。

int semget(key_t key,int nsems, int semflg)
例子:
	semid = semget(key, 1, IPC_CREAT|0666)

参数key
可以自定义产生,一般由key = ftok(".",1);产生
参数nsems
是信号量集里面的信号量的个数,该参数只在创建信号量时有效
参数semflg
是信号量的操作类型以及操纵权限
IPC_CREAT:如果内核存在键值和key相同的信号量集,则返回信号量集的标识符;如果不存在,则创建新的信号量集
IPC_CREAT|IPC_EXCL:如果内核中不存在键值和key值相等的信号量值,则新建一个消息队列;如果存在则报错。

semop

操作信号量集

int semop( int semid, struct sembuf semoparray[], size_t nops );
void pKey(int semid)
{
        struct sembuf sops;

        sops.sem_num = 0; 
        sops.sem_op  = -1;      
        sops.sem_flg = SEM_UNDO;

        semop(semid,&sops,1);
}
void vKey(int semid)
{
        struct sembuf sops;

        sops.sem_num = 0;
        sops.sem_op  = 1;       
        sops.sem_flg = SEM_UNDO;

        semop(semid,&sops,1);
}

参数semoparray
sem_num:
操作信号在信号集中的编号,第一个信号的编号为0
sem_op :
正数
释放相应的资源数,将sem_op的值加到信号量的值上,如果sem_flag指定了SEM_UNDO(还原)标记,那么相应信号量的semadj值会减掉sem_op的值。
0
进程阻塞知道信号量的值为0,当信号量值为0时立即返回;如果信号量的值不为0,相应信号量的semzcnt加1,调用调用线程被阻塞。
负数
对该信号量执行等待操作,当信号量的当前值semval >= -sem_op时,semval减掉sem_op的绝对值,为该线程分配对应数目的资源。如果指定SEM_UNDO,相应信号量的semadj就加上sem_op的绝对值。当semval < -sem_op时,相应信号量的semncnt就加1,调用线程被阻塞,直到semval >= -sem_op,当此条件满足时,调用线程被唤醒,执行相应的分配操作,然后semncnt减去1.

sem_flag:信号量操作的属性标志,如果为0,表示正常操作,如果为IPC_WAIT,使对信号量的操作时非阻塞的。即指定了该标志,调用线程在信号量的值不满足条件的情况下不会被阻塞,而是直接返回-1,并将errno设置为EAGAIN。如果为SEM_UNDO,那么将维护进程对信号量的调整值,以便进程结束时恢复信号量的状态。

下面解释一下与单个信号量相关的几个值:
semval:信号量的当前值,在文章开头信号量的结构中已提到。
semncnt:等待semval变为大于当前值的线程数。在文章开头信号量的结构中已提到。
semzcnt:等待semval变为0的线程数。在文章开头信号量的结构中已提到。
semadj:指定信号量针对某个特定进程的调整值。只有sembuf结构的sem_flag指定为SEM_UNDO后,semadj才会随着sem_op而更新。
讲简单一点:对某个进程,在指定SEM_UNDO后,对信号量semval值的修改都会反应到semadj上,当该进程终止的时候,内核会根据semadj的值,重新恢复信号量之前的值。

struct sembuf sem_opt_wait[0] = {0, -1, SEM_UNDO};

struct sembuf sem_opt_wakeup1[1] = {0, 1, SEM_UNDO};

semctl

控制信号量的信息

int  semctl(int _semid  ,int _semnum,int _cmd  ……);

第三个参数cmd

·IPC_STAT读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。
·IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。
·IPC_RMID将信号量集从内存中删除。
·GETALL用于读取信号量集中的所有信号量的值。
·GETNCNT返回正在等待资源的进程数目。
·GETPID返回最后一个执行semop操作的进程的PID。
·GETVAL返回信号量集中的一个单个的信号量的值。
·GETZCNT返回正在等待完全空闲的资源的进程数目。
·SETALL设置信号量集中的所有的信号量的值。
·SETVAL设置信号量集中的一个单独的信号量的值。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值