p、v 操作的实现
数据结构
typedef struct {
int value; // 可用资源数量
struct PCB *list; // 等待pcb队列
}semaphore;
p 操作
void p(semaphore S) {
S.value --;
if(S.value < 0) { // < 0 表示无可用资源
将该进程加入到 S.list 队列
block() 阻塞该进程
}
}
v 操作
void v(semaphore S) {
S.value ++;
if(S.value <= 0){ // 表示等待队列中仍有进程等待唤醒
从S.list 移出对头 Q
唤醒 Q 进程
}
}
p、v 操作的理解
p、v 操作是基于结构型信号量的进程互斥,同步的通用原子操作
如果只是单纯的用一个整型信号量来解决进程互斥,同步问题,那么如果信号量小于0,则会一直循环占用 cpu 资源,出现“忙等”现象,利用结构型信号量,可用将进程阻塞并放入队列,解放 cpu 资源,提高 cpu 利用率
因为信号量表示可用资源的数量,所以对于互斥情况,信号量为 1 ,表示可用资源只有一个,必须互斥使用。
若可用资源有 n 个,那么信号量为 n