信号量,PV操作

它从整型信号量->记录型信号量,进而发展为“信号量集”机制
信号量集,就是信号量的集合
现在要用的是记录型信号量
1,信号量干嘛用的?
信号量:解决进程间同步与互斥问题
2.信号量的组成
信号量:分很多种,在此写记录型信号量(record semaphore):
信号量组成:每个信号量s除一个整数值s.value(计数)外,还有一个进程等待队列s.L,其中是阻塞在该信号量的各个进程的标识

信号量S>=0时,S表示可用资源的数量

当S小于零时,其绝对值则表示正在等待使用临界区的进程数,
其实就是有多少个进程进行了P操作,结果发现别的进程再用,被加入了等待队列中。

信号量,仅仅由PV操作能改变他的值。也有说法是:假定一个信号量为一个消息。

1.为什么叫PV操作,?
因为是发明人用荷兰文定义的,在荷兰文中,通过叫passeren ,释放叫vrijgeven 。P表示通过,V表示释放。
2.什么是PV操作?
通俗一点,P操作是进厕所然后上锁,V操作 是出厕所开锁。S表示可以用的厕所数量。刚开始总有一个能用

PV操作有P操作原语和V操作原语组成
用PV操作来管理共享资源时,首先要确保PV操作自身执行的正确性。由于P(s)和V(s)都是在同一个信号量S上操作,为了使得它们在执行时,不发生因交叉访问信号量S而可能出现的错误。约定p(s)和V(s)必须是两个不可被中断的过程。即让他们在屏蔽中断下执行。把不可被中断的过程称之为原语。
信号量初始为1时,p操作消息到达,,意味着S值>=0
3.PV操作干了些啥?
P操作的主要动作:

1.S减1; 2若s减1后仍大于或等于0,则进程继续执行
3.若s减1后小于0,则该进程被阻塞后放入等待该信号量的等待队列中,然后转进程调度

信号量初始为1时,v操作消息到达意味着S<0

V操作的主要动作:
1.s加1.
2若相加后结果大于0,则进程继续执行
3.若相加后结果小于或等于0,则从改该信号的等待队列中释放一个等待进程,然后再返回源精粹执行或转进程调度

通俗理解就是在商场上厕所的过程。
P操作:看有没有厕所,有就去,没有就等,排队。
V操作:上完出来,走人,看有没有人等,有就等的人来。
4.同步与互斥的区别联系
同步:则是把异步环境下的一组并发任务因直接制约而互相发送消息,进行互相合作,互相等待,使得各任务按一定的速度执行的过程,具有同步关系的一组并发任务称为合作任务,合作任务间互相发送的信号称为消息或事件。
互斥是指两个或两个以上任务,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间相关的错误

同步:是指为了避免错误,在一个进程访问共享数据时,另一个进程不访问改数据,
互斥:是指,两个进程不能同时在一个临界区中,使用同一个可重复使用的资源。

互斥与同步的区别:互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性,但互斥无法限制访问者对资源的访问顺序。、
同步:大多数情况是互斥的,但他还规定了某种先后次序来运行,这种先后次序依赖于要完成的特定任务

比如:生产者与消费者模型,必须生产者先运行,将数据放到共享区,消费者后运行,将数据从共享区取出。这就是同步。生产者在写的时候,消费者只能等,不能同时使用一块共享资源。这就是互斥。

信号量(Semaphore)是一种用于多进程/线程同步的机制,它可以保证在同一时刻只有一个进程/线程访问共享资源。信号量有两种操作:P(wait)操作和V(signal)操作。 P操作也称为wait操作,是对信号量进行减1操作。如果信号量的值为0,则该操作会使当前进程/线程阻塞,直到有其他进程/线程对信号量进行V操作为止。 V操作也称为signal操作,是对信号量进行加1操作。如果有其他进程/线程因为P操作而被阻塞,那么该操作会唤醒其中一个被阻塞的进程/线程。 下面是一个基本的信号量PV操作的代码实现(用C语言实现): ``` typedef struct { int value; // 信号量的值 struct process *list; // 等待该信号量进程/线程队列 } semaphore; // P操作 void P(semaphore *s) { s->value--; // 信号量值减1 if (s->value < 0) { // 如果信号量的值小于0,当前进程/线程被阻塞 add_to_list(s->list, current_process); // 将当前进程/线程加入等待队列 block(current_process); // 阻塞当前进程/线程 } } // V操作 void V(semaphore *s) { s->value++; // 信号量值加1 if (s->value <= 0) { // 如果等待该信号量进程/线程队列不为空,则唤醒其中一个进程/线程 process *p = remove_from_list(s->list); unblock(p); // 解除该进程/线程的阻塞状态 } } ``` 在上述代码中,`add_to_list`函数和`remove_from_list`函数分别用于将进程/线程加入/移出等待该信号量的队列中。`block`函数和`unblock`函数分别用于阻塞和解除阻塞进程/线程的状态。这些函数的实现可以根据具体需求进行编写。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值