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 调度和分派的基本单位,它是 比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源 (如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。 具体区别如下:

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

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

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

相关推荐
小Pawn爷26 分钟前
14.VMmare安装ubuntu
linux·运维·ubuntu
冷雨夜中漫步28 分钟前
Python快速入门(6)——for/if/while语句
开发语言·经验分享·笔记·python
engchina1 小时前
WSL Ubuntu で Kubernetes v1.34.2 + Docker 環境を構築する
ubuntu·docker·kubernetes
HABuo1 小时前
【linux文件系统】磁盘结构&文件系统详谈
linux·运维·服务器·c语言·c++·ubuntu·centos
Gain_chance3 小时前
34-学习笔记尚硅谷数仓搭建-DWS层最近一日汇总表建表语句汇总
数据仓库·hive·笔记·学习·datagrip
Gain_chance4 小时前
36-学习笔记尚硅谷数仓搭建-DWS层数据装载脚本
大数据·数据仓库·笔记·学习
肖永威4 小时前
macOS环境安装/卸载python实践笔记
笔记·python·macos
暗光之痕5 小时前
Unreal5研究笔记 Actor的生命周期函数
笔记·unreal engine
Gain_chance5 小时前
35-学习笔记尚硅谷数仓搭建-DWS层最近n日汇总表及历史至今汇总表建表语句
数据库·数据仓库·hive·笔记·学习
宵时待雨5 小时前
STM32笔记归纳9:定时器
笔记·stm32·单片机·嵌入式硬件