记linux下进程间通信方式之信号量--对信号量的学习

对信号量的学习

前面已经学习了共享内存的几个api函数,在两个进程间通信时,一个进程进行读操作,一个进程进行写操作,这种情况下,可以保证原子性,但是当有同一时刻有多个进程对该共享内存进行写操作时,就可能导致数据的丢失,前面写的函数就不适用了,这个时候,信号量就可以派上用场。

信号量的概念

信号量作为进程间通信的一种方式,实际上并不能作为数据交换的载体,而是一种类似锁地机制,几个进程间都可以通过获取到同一个信号量的值,判断能否对一个被信号量所“锁住”的临界资源此时能否读取。

有关POSIX 信号量的函数

1. int sem_init(sem_t *sem,int pshared,int value)函数

作用:初始化信号量
返回值:创建成功返回0,失败返回-1
形参:
sem : 要初始化的信号量
pshared : 设定该信号量的作用域,为1时多个进程都可访问,为进程间共享
为0时则作用域是局部的,可供线程间共享
value : 初始化的信号量的值

2. int sem_wait(sem_t *sem)

作用:进行-1操作
返回值:操作成功返回0,失败则返回-1

3. int sem_post(sem_t *sem)

作用:对信号量进行+1操作
返回值:操作成功返回0,失败返回-1

4.sem_destroy(sem_t *sem)

作用:销毁信号量
返回值:成功返回0,失败返回-1

有名信号量与无名信号量的区别

有名信号量会存在内核中,当两个进程同时需要用到一个信号量而缺少sem_t *sem的值的时候,可使用有名信号量为信号量分配一个名字,从而调用sem_open函数来获取sem的值,由于我对信号量的学习是为了封装共享内存,而在共享内存中可划分出一份区域来存储sem的值,所以用无名信号量即可实现多个进程之间的同步。故对有名信号量不进行过多的阐述。

信号量在共享内存中的具体应用思路

首先在共享内存中划分几块区域,分别是 头部 和 数据部分。在头部可以设为结构体数据类型并放几个信号量在里面,分别命名为mutex,full,empty
mutex作用:起互斥作用,mutex只有0和1两个值,当进程要访问共享内存的数据部分时,需要先sem_wait(&mutex),只当mutex为1时,可以被“wait”,当其他某一个进程在访问这块共享内存时,mutex为0,剩下的进程都会在等待mutex为1;
full作用:起计数作用,可以将共享内存的数据部分分为若干个块,用full来记录有数据的块数,当一个进程要对共享内存进行读操作时,首先需要sem_wait(&full),以此来判断时候有空间可写,如果有才进行sem_wait(&mutex)操作,这里要注意两个函数的调用顺序不能对调,否则就会出现死锁现象(一个进程成功访问了数据域,但是没有空间可写,就一直在等待full大于0,从而没有释放mutex,导致其他进程无法进行读操作,这样full就一直不会被+1)
在数据读完毕后,先释放mutex,再对empty进行+1操作
empty作用:类似于full,empty用来记录空的数据块,剩下的过程与full类似,可推得

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值