信号量 PV 操作

信号量的类型定义

一般来说,信号量(semaphore)\(S\),表示资源数量减去需求数量。信号量的值仅能由 PV 操作来改变。

执行一次 P 操作意味着请求一个单位资源,因此 \(S\) 的值减 1;当 \(S < 0\) 时,需求数大于资源数,即已经没有可用资源,请求者必须等待。

执行一个 V 操作意味着释放一个单位资源,因此 \(S\) 的值加 1;若 \(S \ge 0\),此时资源数目能满足需求,所以可以唤醒一个在等待的请求者,让它获取资源。

当 \(S < 0\),\(|S|\) 即没有得到资源的请求者数目,也就是阻塞的线程数。

用互斥量和条件变量可以模拟信号量的行为:

use std::sync::Condvar;
use std::sync::Mutex;

pub struct Semaphore {
    sem: Mutex<i32>,
    con: Condvar,
}

impl Semaphore {
    pub fn new(sem: i32) -> Self {
        Self {
            sem: Mutex::new(sem),
            con: Condvar::new(),
        }
    }

    pub fn p(&self) {
        let mut sem = self.sem.lock().unwrap();

        *sem -= 1;
        if *sem < 0 {
            let _ = self.con.wait(sem).unwrap();
        }
    }

    pub fn v(&self) {
        let mut sem = self.sem.lock().unwrap();

        *sem += 1;
        if *sem <= 0 {
            self.con.notify_one();
        }
    }
}

互斥

当信号量的初始值取 1,任何第二个请求资源者会陷入饥饿。从而同一时刻只能有一个线程访问某个资源。

初始化一个信号量 mutexSemaphore::new(1),在使用临界资源之前调用 mutex.p(),使用完资源之后调用 mutex.v()。即实现了资源的互斥访问。

同步

设置起始资源为大于 1 的正数,则 PV 操作维护资源同步。

举例说明,要实现有 3 个缓冲区的、MPMS 的队列。抽象出两种资源:缓冲区空间(room)和队列中的数据(data)。队列为空的情况下,有 3 个 room 资源,没有 data 资源。

let room = Semaphore::new(3);
let data = Semaphore::new(0);
let queue = Queue::empty();

要往队列里添加元素,则需要一个 room 资源,操作完之后产生一个 data 资源。

room.p();
queue.push(x);
data.v();

要从队列头取出元素,则需要一个 data 资源,操作完之后产生一个 room 资源。

data.p();
let x = queue.pop();
room.v();

(完)

原文地址:https://www.cnblogs.com/gu-castle/p/11436921.html

时间: 2024-10-08 08:34:20

信号量 PV 操作的相关文章

Operating System-进程/线程内部通信-信号量和PV操作

本文介绍操作系统进程管理的两个核心概念: 信号量 PV操作 一.信号量介绍 1.1 信号量引入 信号量(Semaphore)1965年由Dijkstra引入的.信号量一般由一个值是一个变量,其值有可能是0,或者一个正数,或者是负数: 0表示没有资源可以使用 大于0,标识可用资源的数量 小于0,其绝对值表示等待这个资源的进程的个数 针对信号量,Dijkstra提出了两个操作: P操作 V操作 信号量的值只有通过PV操作来完成. 1.2 PV原语操作(atomic action) PV操作里面会有一

【软考】PV操作同步互斥

进程 在操作系统中,进程是占有资源的最小单位(线程可以访问其所在进程内的所有资源,但线程本身并不占有资源或仅仅占有一点必须资源),一个进程能有多个线程. 临界资源 指一次只能有一个进程在占用的资源.如现实中的衣服.一件衣服只能一个人在穿.比如一个硬盘.有两个进程对同一块区域进行写操作.数据不就一锅粥了么= = 临界区 在一个进程占有临界资源的时候.别的进程不能占有.这是互斥.从进程占有资源到资源被释放.这一段代码就叫临界区. 临界区原则(有空即进-无空则等-有限等待-让权等待) 个人造词= =

Operating System-进程/线程内部通信-信号量、PV操作的实现和应用(解决哲学家进餐和生产者消费者问题)

本文主要内容: 信号量的实现 利用信号量解决哲学家用餐问题 利用信号量解决生产者消费者问题 一.信号量的实现 1.1 信号量结构 typedef struct { int value; struct process * list } semaphore; value代表当前信号量可以使用的数量,list代表当前信号量上所等待的进程. 1.2 P操作实现 P(semaphore * s) { s.value--; if(s.value < 0) { add current process to s

信号量与PV操作

在操作系统中进程之间经常会存在互斥和同步两种关系.为了有效处理这种情况,W.Dijskra在1965年提出信号量和PV操作的概念(1)信号量:一种特殊的变量,表现形式是一个整型S和一个队列(2)P操作:也成为"down()和wait()操作",使S=S-1,若S<0,进程暂停执行并放入信号量的等待队列.(3)V操作,也称为"up()和signal()操作",使S=S+1,若S<=0,唤醒等待队列中的一个进程. PV操作属于进程的低级通信. 利用信号量和P

信号量上的PV操作

---恢复内容开始--- 进程通常分为就绪.运行和阻塞三个工作状态.三种状态在某些条件下可以转换,三者之间的转换关系如下: 进程三个状态之间的转换就是靠PV操作来控制的.PV操作主要就是P操作.V操作和信号量.其中信号量起到了至关重要的作用. 信号量 信号量是最早出现的用来解决进程同步与互斥问题的机制. 信号量(Saphore)由一个值和一个指针组成,指针指向等待该信号量的进程.信号量的值表示相应资源的使用情况.信号量S>=0时,S表示可用资源的数量.执行一次P操作意味着请求分配一个资源,因此S

用信号量及其PV操作处理实际问题

1.书上课后练习P187-43 semaphore mutex , sweat , water ,orange ; semaphore empty; process Supply(){ while(1){ P(empty) ; 产生一个0-2的随机数 ; if(s==0) V(sweat) ; else if( s==1) V(water); else V(orange) ; } } process P1(){ while(1){ P(orange) ; P(mutex) ; V(mutex)

PV操作,我终于懂你了!

上个星期,米老师给我们讲课实在是精彩!本人终于对Pv操作有了自己的理解.之前一直不太理解Pv操作,现在总结一下,以供下阶段学习和总结. 为什么叫PV操作?原因是:这是狄克斯特拉用荷兰文定义的,因为在荷 兰文中,通过叫passeren,释放叫vrijgeven,PV操作因此得名. 这张图乍一看谁也不知道我想说明什么.我想通过这张图来给大家解释一下PV操作! 中间这加粗的黑线是秤杆,就像我们生活中的上下控制的电源开关!只有两个状态,一个是向上,一个是向下. 这张图的上面是消费者(儿子),对于消费者来

clients(PV操作共享内核内存进行输入输出分屏) - server(进程间通信)模型实现

1.拓扑结构 2.PV操作共享内核内存进行输入输出分屏 (1) 1 int semop(int semid,struct sembuf *sops,size_t nsops): 功能描述 操作一个或一组信号. semid: 信号集的识别码,可通过semget获取. sops: 指向存储信号操作结构的数组指针,信号操作结构的原型如下 1 struct sembuf 2 { 3 unsigned short sem_num; /* semaphore number */ 4 short sem_op

软考征程之Pv操作

一.概念 1.PV操作的含义 PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S):①将信号量S的值减1,即S=S-1: ②如果S30,则该进程继续执行:否则该进程置为等待状态,排入等待队列. V(S):①将信号量S的值加1,即S=S+1: ②如果S>0,则该进程继续执行:否则释放队列中第一个等待信号量的进程. PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥.PV操作属于进程的低级通信. 2.进程的同步和互斥 同步:指在并发进程之