操作系统——PV操作

  操作系统这本书里有一章是讲进程的,其中一节讲的进程同步,一开始看的有点懵,尤其里边那几行代码。后来看到个视频里讲解P–V操作,说的就是这个,豁然开朗。
  P–V操作(也称同步操作):
  
  同步机制应该遵循的准则:
  1. 空闲让进
  2. 忙则等待
  3. 有限等待
  4. 让权等待
  
一些概念:
  

  临界资源:诸进程需要互斥方式对其进行共享资源,如打印机、磁带机。
  临界区:每个进程访问临界资源的那段代码。

  P操作(申请资源):也称为down()、wait()操作 使S=S-1,若S<0,进程暂停执行,放入信号量的等待队列。
  V操作(释放资源):也称为up()、signal()操作,使S=S+1,若S<=0,唤醒等待队列的一个进程。

下面以一张仓库搬运工的图来看一下P–V操作是怎么进行的:

这里写图片描述

这整个的工作流程是把A仓库的货物搬到B仓库。
搬运工甲在中转站空闲的时候可以把A仓库的货物搬到中转站,也就是执行P操作。
搬到中转站之后换搬运工乙来执行V操作,把货物搬到B仓库。

这个是单缓冲区,也就是一个缓冲区的,下面来看一下书上的一个经典的进程同步问题:读者—写者问题:

首先这个问题的条件是:

  • 允许多个读者同时执行读操作;
  • 不允许读者、写者同时操作;
  • 不允许多个写者同时操作。

读者优先:

读者来:
   1. 无读者、写者,新读者可以读
   2. 有写者等,但有其他读者正在读,则新读者也可以读
   3. 有写者写,新读者等
写者来:

  1. 无读者,新写者可以写
  2. 有读者,新写者等
  3. 有其他写者,新写者等

它的PV原语可以写成如下:

生产者:消费者:
生产一个产品;P(s2);
P(s1);P(mute);
P(mute);从缓冲区取产品;
送产品到缓冲区;V(mute);
V(mute);V(s1);
V(s2);消费产品;

s1初值为n,s2初值为0,mute(缓冲区资源)初值为1.

先说到这里,理解不深,如果大家有不准确或不清楚的地方可以和小编交流交流。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 33
    评论
在Linux操作系统中,可以使用信号量(Semaphore)来实现进程间的互斥访问共享资源,例如打印机。下面是一个简单的示例代码,演示了如何使用PV操作来实现多个进程共享一台打印机的互斥访问[^1]: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/sem.h> #define KEY 1234 void P(int semid) { struct sembuf buf; buf.sem_num = 0; buf.sem_op = -1; buf.sem_flg = SEM_UNDO; semop(semid, &buf, 1); } void V(int semid) { struct sembuf buf; buf.sem_num = 0; buf.sem_op = 1; buf.sem_flg = SEM_UNDO; semop(semid, &buf, 1); } int main() { int semid; pid_t pid; // 创建信号量 semid = semget(KEY, 1, IPC_CREAT | 0666); if (semid == -1) { perror("semget"); exit(1); } // 初始化信号量 semctl(semid, 0, SETVAL, 1); // 创建子进程 pid = fork(); if (pid == -1) { perror("fork"); exit(1); } if (pid == 0) { // 子进程 P(semid); // 进入临界区 printf("Child process is printing...\n"); sleep(2); // 模拟打印过程 printf("Child process finished printing.\n"); V(semid); // 离开临界区 } else { // 父进程 P(semid); // 进入临界区 printf("Parent process is printing...\n"); sleep(2); // 模拟打印过程 printf("Parent process finished printing.\n"); V(semid); // 离开临界区 } // 删除信号量 semctl(semid, 0, IPC_RMID); return 0; } ``` 这段代码使用了System V信号量机制,通过`semget`函数创建一个信号量集合,然后使用`semctl`函数初始化信号量的值为1。在子进程和父进程中,分别调用`P`函数和`V`函数来实现进入和离开临界区的操作。其中,`P`函数将信号量的值减1,如果信号量的值小于0,则进程被阻塞;`V`函数将信号量的值加1,如果有进程因为等待信号量而被阻塞,则唤醒其中一个进程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值