ipc通信四—信号量

信号量

有两个以上的任务(进程/线程)并发的实体,去访问同一个共享资源(硬件上,软件上)的时候,那么要保证访问的这个共享资源是有序访问,如果不是有序访问有可能造成不可预知后果。

very_important_i = 5;
func()
{
   
very_important_i ++;
}

有两个实例(任务),调用 func 函数,那么 very_important_i 最后的值是多少?
有可能是6,还有可能是7。
6的结果不是我们想要,所有我们要保证多个实例能够有序的去访问,就需要对共享资源进行某种保护,以便实例可以有序的访问,避免竞争

分析: 并发---->竞争---->共享资源的非法访问 ---->程序行为异常…
解决方法: 能不能不用并发? 显然不行
在保留并发前提下,“ 避免竞争 ” ===> 访问共享资源的时候,严格串行!!!!

信号量机制

信号量是个什么玩意?
信号量的作用是什么?
为什么要用到信号量?
信号量是怎么达到目的的?

信号量是个什么玩意?

信号量(semaphore)是一种用于提供不同进程的间或一个进程内部不同线程间的同步的一种机制。

进程/线程:任务,并发的实体
同步:并发实体间,相互等待相互约束的,有序的,有条件的访问。
信号量就是为了保护共享资源,让共享资源有序的访问的一种机制。
信号量目标:为了保护共享资源,使其能够被有序访问。

信号量是我们程序界最高尚的一种东西,因为它不是为了自己存在而存在,是为了别人而存在的。(它 保护的对象,共享资源)“ 保镖

什么时候使用信号量?

有保护对象的时候,才需要信号量
首先搞清楚,谁需要保护,保护谁?
一个被保护对象,需要一个信号量。

如何来保护?

“ 保护 ”是指,让这个被保护对象( 共享资源 )有序的访问。如: “ 互斥 ”
“ 共享资源 ”:大家都访问的资源。
**信号量机制:**其实是程序员之间的一种约定,用来保护共享资源的。比如说进程A和进程B,都要访问一个互斥设备,那么我们可以使用一个信号量来表示能不能访问该设备,然后每个进程访问该设备的时
候,先去访问信号量,如果能访问设备就把信号量设置为“ NO ”,访问完毕之后再将信号量设置为 “YES ”。
在访问共享资源的时候,先去判断,共享资源是否能够访问。
能访问:你就获取到了该信号量( 变成不可访问 ),则进入能访问之后的代码。
不能访问: wait 直到信号量变成:能访问。
访问共享资源的代码区域叫做:临界区

LOCK 上锁
操作共享资源的代码
UNLOCK 解锁

信号量是如何实现的?

信号量大家都可以访问的一个整数。
一个进程/线程可以执行以下三种操作:
创建 ( create ) 一个信号量这还要求调用者指定信号量的初始值。
初始值表示该信号量保护的共享资源,可以同时被多少个任务访问。
sem --> 5 表示此刻有5个进程或者线程去同时访问它所保护的共享资源。
sem --> 1 表示此刻有一个进程或者线程可以去访问它所保护的共享资源。“ 互斥信号量 ”
等待( wait )一个信号量
该操作会测试这个信号量的值,如其值 <= 0,那么会等待( 阻塞 )一旦其值>0,这个时候,将它-1,并继续往下执行临界区代码。
其函数实现如下:

while(semaphore_value <= 0)
{
   
while(1);// wait block .... 卡死在这里
}
semaphore_value--; // 表示该进程/线程获取到了信号量
// 下面的代码就是对于获取到该信号了之后,对共享资源的操作

上述操作必须是 “ 原子操作 ”: 不允许有两个及以上的进程同时操作。
P操作: proberen ( 尝试 )荷兰语
down/lock 上锁

释放一个信号量:该操作将信号量的值+1,其函数实现类型如下

semaphore_value++; // 原子操作

V操作: verhogen ( 增加 )荷兰语
up / unlock 解锁

信号量保护的目标是通过如下方式实现:
在临界区的前面加上一个:P操作
在临界区的后面加上一个:V操作

Linux内核信号量的具体实现:

System V 信号量的大概流程
ftok :获取 System V IPC 设施对象的key
semget :在内核中创建或打开一个System V 信号量
P/V操作

System V信号量:
计数信号量集(计数信号量数组):
计数信号量:
该信号量的值可以是> 1 的值,它所保护共享资源允许多个任务同时访问它。
计数值 1 , 0 ===> 互斥信号量
互斥信号量:
该信号量的值要么是1,要么是0,它所保护的共享资源同一时刻只能允许一个任务访
问。

信号量的API函数

semget :用来创建或打开一个System V信号量

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
/*
作用:
用来创建或打开一个System V信号量
@key:
System V IPC设施的key,有ftok返回
@nsems:
要创建
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值