信号量与PV操作

文章目录


信号量与PV操作是操作系统中实现进程同步与互斥的核心机制。

一、核心概念

1. 信号量的本质

信号量是一个特殊的整型变量,可以理解为一个资源计数器。它只能通过两个原子操作(不可被中断的操作)来访问------即P操作和V操作 。

信号量的物理意义:

  • S ≥ 0:表示当前可用资源的数量
  • S < 0:其绝对值表示正在等待该资源的进程数量

2. P操作(Wait / 申请资源)

P操作源自荷兰语proberen (测试),表示进程申请一个资源。执行逻辑如下 :

复制代码
P(S):
    S = S - 1;           // 信号量减1
    if (S < 0) {
        阻塞该进程;
        将其放入等待队列;
    }

说明:先"预订"资源(S减1),再看结果------若S≥0说明资源足够,进程继续;若S<0说明资源已耗尽,进程需等待。

3. V操作(Signal / 释放资源)

V操作源自荷兰语verhogen (增加),表示进程释放一个资源。执行逻辑如下 :

复制代码
V(S):
    S = S + 1;           // 信号量加1
    if (S ≤ 0) {
        从等待队列中唤醒一个进程;
    }

先"归还"资源(S加1),再看结果------若S>0说明无进程等待;若S≤0说明有进程正在等,则唤醒其中一个。

P操作让S"减1",V操作让S"加1"。

P像"probe"(探测):先问有没有资源;

V像"victory"(胜利):用完了释放,别人可以用了。

二、两大核心应用

信号量机制主要解决两类问题:互斥同步。两者的信号量初值设置不同,这是解题的关键区分点 。

1. 实现进程互斥

目标:保证多个进程不能同时进入临界区(访问共享资源)。

方法

  • 设置一个互斥信号量(通常命名为mutex),初值为1
  • 进程进入临界区前执行P(mutex)
  • 进程离开临界区后执行V(mutex)

典型代码框架

复制代码
P(mutex);           // "上锁"
访问临界资源;
V(mutex);           // "解锁"

原理:初值为1表示"临界区只允许1个进程进入"。第一个进程执行P(mutex)后S=0,可进入;第二个进程再执行P(mutex)时S=-1,被阻塞。

2. 实现进程同步

目标:协调进程间的执行先后顺序(一个操作必须在另一个操作之后发生)。

方法

  • 设置一个同步信号量初值通常为0
  • 在"需要先执行"的进程结束后执行V(S)(发信号)
  • 在"需要后执行"的进程开始前执行P(S)(等信号)

典型代码框架

复制代码
// 进程A(先执行)
完成某工作;
V(S);               // 通知进程B

// 进程B(后执行)
P(S);               // 等待进程A的通知
开始某工作;

原理:初值为0表示"信号尚未产生"。若B先执行到P(S),S=-1被阻塞;等A执行完V(S)后S=0,唤醒B。

三、经典模型:生产者-消费者问题

生产者-消费者问题是PV操作的综合应用题,同时涉及互斥和同步,是软考高频考点 。

问题描述

  • 生产者进程生产产品,放入缓冲区
  • 消费者进程从缓冲区取出产品消费
  • 缓冲区大小为n(最多放n件产品)
  • 缓冲区满时生产者需等待,缓冲区空时消费者需等待

信号量设置

信号量 含义 初值 类型
mutex 互斥访问缓冲区 1 互斥信号量
empty 空缓冲区数量 n 同步信号量
full 满缓冲区数量 0 同步信号量

算法框架

复制代码
生产者进程:                    消费者进程:
while(true) {                  while(true) {
    生产一个产品;                   P(full);      // 等有产品
    P(empty);   // 等空位          P(mutex);     // 上锁
    P(mutex);   // 上锁            取产品;
    放产品;                         V(mutex);     // 解锁
    V(mutex);   // 解锁            V(empty);     // 空位+1
    V(full);    // 产品+1          消费产品;
}                              }

P操作的顺序至关重要!必须先P(empty)再P(mutex),否则可能产生死锁------设想缓冲区满时生产者先拿到mutex锁,然后发现empty=0被阻塞,消费者因拿不到mutex无法消费,系统死锁 。

四、练习

题目1 :假设系统中有n个进程共享3台扫描仪,并采用PV操作实现进程同步和互斥。若系统信号量S的当前值为-1,进程P1、P2又分别执行了1次P(S)操作,那么信号量S的值应为( )。

A. 3  B. -3  C. 1  D. -1

答案:B

解析:扫描仪资源数为3,故信号量初值为3。当前S=-1,表示有1个进程在等待资源。P1执行P(S)后S=-2,P2执行P(S)后S=-3。每执行一次P操作,S的值减1 。

题目2 :信号量S的初始值为8,在S上执行了10次P操作,6次V操作后,S的值是( )。

A. 10  B. 8  C. 6  D. 4

答案:D

解析:计算逻辑为:初始值 + V操作次数 - P操作次数 = 8 + 6 - 10 = 4。这是PV操作最基本的值变化计算,P减1,V加1 。

题目3 :假设系统有n(n≥10)个并发进程共享资源R,且资源R的可用数为9。若采用PV操作,则相应的信号量S的取值范围应为( )。

A. 0~9  B. -(n-9)~9  C. -9~9  D. -(9-n)~9

答案:B

解析:信号量最大值=资源初始数=9。最小值发生在所有n个进程都申请资源时:最多9个进程获得资源,剩余n-9个进程被阻塞,S = 9 - n = -(n-9)。故取值范围为[-(n-9), 9] 。

题目4 :在使用信号量实现进程互斥时,信号量的初值应设置为( );为实现进程同步,信号量的初值应设置为( )。

A. 0, 1  B. 1, 0  C. 0, n  D. n, 1

答案:B

解析:互斥信号量初值=1(临界资源一次只能被一个进程访问);同步信号量初值常为0(用于等待事件发生) 。

相关推荐
a里啊里啊4 天前
软考-软件评测师:知识点整理(二)——操作系统基础知识
操作系统·线程·进程·软考·pv操作·软件评测师
代码AC不AC1 个月前
【Linux】System V 通信方式
linux·消息队列·共享内存·信号量·system v
皮皮哎哟2 个月前
Linux多线程通信:告别数据混乱
linux·互斥锁·进程间通信·信号量
熬夜有啥好2 个月前
Linux软件编程——线程间的通信
互斥锁·信号量·软件编程·多线程间的通信
嵌入小生0072 个月前
线程间通信---嵌入式(Linux)
linux·c语言·vscode·嵌入式·互斥锁·线程间通信·信号量
2401_858286112 个月前
OS55.【Linux】理解信号量(不是信号)
linux·运维·服务器·计数器·信号量
HalvmånEver2 个月前
Linux:基于信号量的环形队列与生产者消费者模型(一)
linux·运维·服务器·信号量
柏木乃一3 个月前
进程间通信IPC(3)system V标准下基于责任链模式的消息队列,基于建造者模式的信号量
linux·c++·消息队列·建造者模式·责任链模式·信号量·进程间通信ipc
Trouvaille ~3 个月前
【Linux】线程同步与互斥(三):生产者消费者模型实战
linux·运维·c++·信号量·阻塞队列·生产者消费者模型·环形队列