Linux下进程间通信 之 信号量

         信号量是一种计数器,用于控制对多个进程共享的资源进行的访问。它们常常被用作一个机制,在某个进程正在对特定的资源进行操作时,信号量可以防止另一个进程去访问它。 

        信号量是特殊的变量,它只取正整数值并且只允许对这个值进行两种操作:

        等待(wait)和 信号(signal)。即:(P、V操作,P用于等待,V用于信号) 

        p(sv):如果sv的值大于0,就给它减1;如果它的值等于0,就挂起该进程的执行 

        V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行;如果没有其他进程因等待sv而挂起,则给它加1 。

简单理解就是:P相当于申请资源,V相当于释放资源 

信号量头文件: 

#include <sys/types.h> 
#include <sys/stat.h>
#include <sys/sem.h> 

内核为每个信号量集合都维护一个semid_ds结构:

struct semid_ds{
    struct ipc_perm sem_perm;
    unsigned short sem_nsems;
    time_t sem_otime;
    time_t sem_ctime;
    ...
}

信号量数据结构:

union semun{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buf;
}

信号量操作sembuf结构:

struct sembuf{
    ushort sem_num;//信号量的编号
    short sem_op;//信号量的操作。如果为正,则从信号量中加上一个值,如果为负,则从信号量中减掉一个值,如果为0,则将进程设置为睡眠状态,直到信号量的值为0为止。
    short sem_flg;//信号的操作标志,一般为IPC_NOWAIT。
}

常用函数:

int semget(key_t key, int num_sems, int sem_flags); 
//semget函数用于创建一个新的信号量集合 , 或者访问一个现有的集合(不同进程只要key值相同即可访问同一信号量集合)。第一个参数key是ftok生成的键值,第二个参数num_sems可以指定在新的集合应该创建的信号量的数目,第三个参数sem_flags是打开信号量的方式。
例如:int semid = semget(key, 0, IPC_CREATE | IPC_EXCL | 0666);//第三个参数参考消息队列int 

msgget(key_t key, int msgflag);第二个参数。

int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops); 
//semop函数用于改变信号量的值。第二个参数是要在信号集合上执行操作的一个数组,第三个参数是该数组操作的个数 。
例如:struct sembuf sops = {0, +1, IPC_NOWAIT};//对索引值为0的信号量加一。
semop(semid, &sops, 1);//以上功能执行的次数为一次。

int semctl(int sem_id, int sem_num, int command,...); 
// semctl函数用于信号量集合执行控制操作,初始化信号量的值,删除一个信号量等。 类似于调用    msgctl(), msgctl()是用于消息队列上的操作。
// 第一个参数是指定的信号量集合(semget的返回值),第二个参数是要执行操作的信号量在集合中的索引值(例如集合中第一个信号量下标为0),第三个command参数代表要在集合上执行的命令。
IPC_STAT:获取某个集合的semid_ds结构,并把它存储到semun联合体的buf参数指向的地址。
IPC_SET:将某个集合的semid_ds结构的ipc_perm成员的值。该命令所取的值是从semun联合体的buf参数中取到。
IPC_RMID:内核删除该信号量集合。
GETVAL:返回集合中某个信号量的值。
SETVAL:把集合中单个信号量的值设置成为联合体val成员的值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值