进程间通讯--信号量

要理解信号量,先要理解以下几个概念:

1、 临界资源:同一时刻,只能被一个进程访问的资源。

2、临界区:访问临界资源的代码区域。

3、原子操作:任何情况下都不能被打断的操作。

4、内核对象:用于对进程间通讯时,多进程能同时访问同一资源的记录。


做个比方,有一个停车位,同一时刻只能停放一辆车,那么该停车位就相当于一个临界资源,车从停放到开走所使用临界资源的过程就是我们所说的临界区,而且在停放的全过程中别的车不能停放就相当于原子操作。可是,当有第二辆车来的时候,并不知道停车位已经被占了,此时,就产生了竞争行为,显然,很不好,因此为了和平的使用停车位,我们有一个停车场看门人,他会时实的记录停车位的使用情况,占用一个车位就减1,腾出一个就加1。类似的信号量就如我们所说的停车场看门人。


下面详细的介绍 信号量:对于一个资源,能同时被几个进程访问的计数器。有地方也说信号量是一种睡眠锁,关于锁的概念,后面再提及。
假如进程A先持有信号量M,然后进程B试图获得A正在使用的M(假设此时M资源为1),信号量会把B放入等待队列,只有当A释放掉信号量M时,B进程才会获得,从而执行自己的代码。

信号量的这种特性,我们得到信号量的作用:控制进程同步

信号量的函数操作:

以下函数所需头文件都有

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

(1)、创建或者获取:

函数int  semget((key_t)  key,int   nsems, int  semflg)
key的含义信号量的键值,不同信号量使用同一个信号量键值来获得同一个信号量。
nsems的含义需要创建信号量的数目,通常取值为1。
semflg的含义与open函数权限位一样。使用IPC_CREAT标志创建信号量,如果同一键值的信号量存在,返回原有信号量的ID;不存在,创建一个新的信号量。同时使用IPC_EXCL | IPC_CREAT标志,则创建一个新的唯一的信号量,如果存在,则出错。
返回值成功返回一个非负数的信号量标示符;失败返回-1.

(2)、初始化和删除

创建的信号量不需要初始换;获取的信号量一定要初始话化。

函数int   semctl(int   semid,int   semnum,int   cmd,union   semun   arg)
semid信号量标示符。
semnum的含义信号量编号,可以理解为数组的下标,通常取值为0,表示要操作第一个信号量。
cmd的含义采取的操作:IPC_SETVAL表示将信号量设为arg中val的值;IPC_RMID表示从系统中删除。
arg的含义定义信号量时是一个联合体,结构为:
union  semun{
int   val;
struct   semid_ds   *buf;
unsigned   short    *array;
}
返回值成功返回0;失败返回-1。

(3)、PV操作

P操作:减1操作。

V操作:加1操作。

函数int  semop(int   semid,struct   sembuf   *sops,size_t   num_sem_ops)
semid信号量标识符
sops的含义指向一个结构体的指针;
struct   sembuf{
short    sem_num;//信号量编号
short    sem_op;//为-1时是p操作;为1时是v操作;
short    sem_flg;/*通常设为SEM_UNDO,表示在进程中如果没有释放而退出时,系统自动释放该进程中未释放的信号量;这个设置应该作为一个良好的习惯。*/
}
num_sem_ops的含义操作sops中的元素数目。
返回值成功返回0;失败返回-1。

这样冗杂的操作,我们利用封装函数,来提供给用户一个简单的接口更好一点。

封装函数:

在mysem.h中对每个函数声明。在mysem.c中实现对每个函数的封装,如下:



来写两个例子对信号量加以运用:

例一:A进程接受用户输入,当用户输入“ok”时,B进程输出100以内的素数。此时可以理解为A和B进程之间是服务关系,我们把v.val设为0,既停车位刚开始为0,等到输入ok时,产生停车位。

进程A:(sema.c)

进程B:(semb.c)

显示结果:


例二:我们将封装函数中v.val改为1;利用父子进程来实现两进程之间的竞争关系,如下:

当不使用信号量时(mysem_text1.c)与使用信号量时(mysem_text2.c),如下:

      对比

运行:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值