03在Ubuntu中验证PV操作

一、 实践目的

1) 学习多线程操作(Pthread库)

2) 学习Linux中PV操作对应的实现

二、实践环境

1)Vmware WorkStation Pro

2)虚拟机操作系统:Ubuntu20.04

三、问题描述

桌上有一只盘子,每次只能放入一个水果。爸爸专放苹果,妈妈专放橘子,一个儿子专等吃盘子中的橘子,一个女儿专等吃盘子中的苹果。分别用P、V操作和管理实现。

四、实践内容

·线程和进程的互斥和同步

同步是操作系统级别的概念,是在多道程序的环境下,存在着不同的制约关系,为了协调这种互相制约的关系,实现资源共享和进程协作,从而避免进程之间的冲突,引入进程同步。

进程互斥是间接制约关系。当一个进程进入临界区使用临界资源时,另一个进程必须等待。只有当使用临界资源的进程退出临界区后,这个进程才会解除阻塞状态。

·信号量和P、V操作

通过设置一个表示资源个数的信号量S,通过对信号量S的P、V操作来实现进程的同步与互斥。P、V操作分别来自荷兰语Passeren和Vrijgeven,分别表示占有和释放。P、V操作是操作系统的原语,意味着具有原子性。

P操作首先减少信号量,表示有一个进程将占有或等待资源,然后检测S是否小于0,如果小于0则阻塞,如果大于0则占有资源进行执行。

V操作是和P操作相反的操作,首先增加信号量,表示占用或等待资源的进程减少了1个。然后检测S是否小于0,如果小于0则唤醒等待使用S资源的其它进程。

·题目分析

(1)设有两个篮子,分别有若干个苹果或橘子,爸爸和妈妈将每次从水果篮子中拿出一个水果放入水果盘中,儿子女儿则挑选各自喜欢的水果。

(2)Father、mother、son、daughter是四个线程或进程。

(3)盘子plate是它们的共享变量,对盘子的操作要互斥。

(4)Father和daughter要对apple同步。

(5)Mother和son要对orange同步。

·用P、V操作实现(伪代码)

bash 复制代码
empty,full1,full2:semaphore;
  empty:=1;full1:=0;full2:=0;
cobegin
  repeat father;
  repeat mother;
  repeat son;
  repeat daughter;
coend;
procedure father
begin
  p(empty);
  放苹果入盘:
  v(full1);
end;
procedure mother
begin
  p(empty);
  放橘子入盘;
  v(full2);
end;
procedure son
begin
  p(full2);
  从盘中取橘子;
  v(empty);
  吃橘子;
end;
procedure daughter
begin
  p(full1);
  从盘中取苹果;
  v(empty);
  吃苹果;
end;

·实验过程

(1)安装必要的库,包括POSIX线程(pthread)和信号量(semaphore)。


(2)创建一个fruit_plate.c文件,并编写代码。键入vim fruit_plate.c进行编写。



在该程序中,为了让进程在有限次数内结束循环,我假定爸爸手头有五个苹果A,B,C,D,E,妈妈手头有五个橘子A,B,C,D,E。并引入usleep函数来模拟爸爸放苹果的时间为1秒,妈妈放橘子的时间为1.5秒,儿子吃橘子的时间为2秒,女儿吃苹果的时间为2.5秒。sem_wait和 sem_post分别对应P和V操作,用于同步和互斥。sem_init初始化信号量,sem_destroy销毁信号量。pthread_create创建线程,pthread_join等待线程结束。信号量 plate_sem用于互斥访问盘子,确保每次只有一个线程可以放入或取走水果。信号量 apple_sem和 orange_sem用于同步,确保女儿和儿子只有在有对应的水果时才能吃。

(3)键入gcc -pthread fruit_plate.c -o fruit_plate编译代码。

(4)键入./fruit_plate运行生成的可执行文件。

五、 小结与改进设想

本次实践后,我对线程和进程也有了更深更具体的体会。进程是具有一定独立 功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调 度的一个独立单位。线程是进程的一个实体,是 CPU 调度和分派的基本单位,它是 比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源 (如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。 具体区别如下:

地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。

通信:线程间可以直接读写进程数据段(如全局变量)来进行通信------需要进程同步和互斥手段的辅助,以保证数据的一致性。

调度和切换:线程上下文切换比进程上下文切换要快得多。

相关推荐
tangyal2 小时前
渗透笔记1
笔记·网络安全·渗透
fanged3 小时前
STM32(5)--HAL1(TODO)
笔记
grd44 小时前
RN for OpenHarmony 小工具 App 实战:屏幕尺子实现
笔记·harmonyos
丝斯20115 小时前
AI学习笔记整理(50)——大模型中的Graph RAG
人工智能·笔记·学习
小+不通文墨6 小时前
“超声波测量声速”实验报告
经验分享·笔记·学习·学习方法
明洞日记6 小时前
【软考每日一练002】进程调度机制详解
c++·ai·操作系统·进程
lihao lihao6 小时前
平衡二叉树
笔记
Code-world-17 小时前
NVIDIA Isaac Sim 安装教程
linux·人工智能·ubuntu·强化学习·isaac sim
JavaLearnerZGQ7 小时前
我的Redis笔记2【分布式缓存】
redis·笔记·缓存