-
进程互斥与同步的定义
- 进程互斥:指多个并发执行的进程因共享某种系统资源(如临界资源),必须以排他方式访问该资源,即在任一时刻只能有一个进程进入临界区执行,其他进程必须等待。这是为避免竞争条件、保证数据一致性而设置的机制。
- 进程同步:指多个相互协作的进程在执行次序上需要协调,通过一定的机制实现进程间的有序推进,例如一个进程需等待另一个进程完成某操作后才能继续执行。同步强调的是进程之间的逻辑依赖关系和时序控制。
-
信号量(Semaphore)的概念
信号量是一种用于解决进程间同步与互斥问题的数据结构,由荷兰科学家Dijkstra提出。它是一个整型变量,包含两个关键属性:- 一个整数值(表示可用资源数量或某种状态);
- 一个等待队列(记录因该信号量而阻塞的进程)。
根据初始值不同,信号量可分为: - 二进制信号量(初始值为0或1):常用于实现互斥(如互斥锁);
- 计数信号量(可取任意非负整数):用于管理多个相同类型的资源。
-
P-V 操作(原语)
P操作(也称wait操作)和V操作(也称signal操作)是对信号量进行的两种原子操作,不可被中断。- P(sem):申请使用资源
P(sem) { sem = sem - 1; if (sem < 0) { 将当前进程插入到sem的等待队列; 阻塞该进程(让出CPU); } } - V(sem):释放资源
V(sem) { sem = sem + 1; if (sem <= 0) { 从sem的等待队列中唤醒一个进程; 被唤醒的进程变为就绪状态; } }
其中,P操作对应“申请-等待”,V操作对应“释放-通知”。两者结合可实现对临界资源的安全访问以及进程间的协调运行。
使用信号量实现进程互斥的核心思想是:将临界资源的访问权限通过一个二进制信号量(初始值为1)进行控制,确保同一时刻只有一个进程可以进入临界区。 - P(sem):申请使用资源
实现步骤:
- 定义一个二进制信号量
mutex,初始值为 1(表示临界资源空闲)。 - 每个进程在进入临界区前执行 P(mutex) 操作,尝试获得访问权。
- 离开临界区时执行 V(mutex) 操作,释放访问权。
- P、V操作必须成对出现,且保证原子性。
示例:基于P-V操作的临界区管理
假设两个进程 Process A 和 Process B 共享一个临界资源(如共享变量 counter),需互斥访问。
// 全局定义信号量 mutex,初始值为 1
semaphore mutex = 1;
// 进程代码结构(以A为例)
void Process_A() {
while (1) {
// 非临界区操作
do_non_critical_section();
// 进入临界区前:P操作
P(mutex);
/* 临界区开始 */
do_critical_section(); // 如:counter++, 文件写入等
/* 临界区结束 */
// 离开临界区后:V操作
V(mutex);
// 剩余操作
do_remaining_section();
}
}
// Process_B 结构相同,使用同一个 mutex 信号量
执行过程说明:
| 时间 | 操作 | mutex 值 | 说明 |
|---|---|---|---|
| t0 | Process A 执行 P(mutex) | 0 | 成功进入临界区 |
| t1 | Process B 执行 P(mutex) | -1 | 资源已被占用,B 被阻塞 |
| t2 | Process A 执行 V(mutex) | 0 | 释放资源,唤醒 B |
| t3 | Process B 被唤醒继续执行 | -1 → 实际变为 0 后运行 | 进入临界区 |
注:当
mutex = 1表示资源可用;0表示被占用;负数表示有进程等待。
关键点总结:
- 互斥信号量初始值必须为 1,表示只有一个资源可供使用。
- P操作在进入临界区前调用,用于申请资源。
- V操作在退出临界区后立即调用,防止死锁或饥饿。
- P、V操作本身必须是原子的,通常由操作系统内核提供支持。
这种方式简单有效,广泛应用于操作系统中对打印机、共享内存、文件等资源的互斥访问控制。

1512

被折叠的 条评论
为什么被折叠?



