操作系统linux系统下实现pv操作Word下载.docx
《操作系统linux系统下实现pv操作Word下载.docx》由会员分享,可在线阅读,更多相关《操作系统linux系统下实现pv操作Word下载.docx(16页珍藏版)》请在冰豆网上搜索。
(3)终端的简单使用
(4)python3.5.2源码安装
2.多线程和多进程同步方法解决水果分配问题:
水果分配的问题:
桌上有一只盘子,每次只能放入5只水果。
爸爸专放苹果,
妈妈专放橘子,一个儿子专等吃盘子中的橘子,一个女儿专等吃盘子中的苹果.用P,V操作实现爸爸、妈妈、儿子、女儿进程的同步控制。
补充:
设有两个篮子,分别有若干个苹果或橘子,爸爸和妈妈将每次从水果篮子中拿出一个水果放入水果盘中,儿子女儿则挑选各自喜欢的水果。
(1)分析问题,写出伪代码
(2)线程实现
(3)进程实现
二、实验目的和要求
1.认识和学会使用linux系统:
Linux是一种可以在PC机上执行的类似UNIX的操作系统,是一个完全免费的操作系统。
1991年,芬兰学生LinusTorvalds开发了这个操作系统的核心部分,因为是Linus改良的minix系统,故称之为Linux.
2.理解线程和进程的互斥和同步原理:
同步是操作系统级别的概念,是在多道程序的环境下,存在着不同的制约关系,为了协调这种互相制约的关系,实现资源共享和进程协作,从而避免进程之间的冲突,引入了进程同步。
进程互斥是间接制约关系。
当一个进程进入临界区使用临界资源时,另一个进程必须等待。
只有当使用临界资源的进程退出临界区后,这个进程才会解除阻塞状态。
3.使用信号量和互斥量解决问题:
通过设置一个表示资源个数的信号量S,通过对信号量S的P和V操作来实现进程的的互斥。
P和V操作分别来自荷兰语Passeren和Vrijgeven,分别表示占有和释放。
PV操作是操作系统的原语,意味着具有原子性。
P操作首先减少信号量,表示有一个进程将占用或等待资源,然后检测S是否小于0,如果小于0则阻塞,如果大于0则占有资源进行执行。
V操作是和P操作相反的操作,首先增加信号量,表示占用或等待资源的进程减少了1个。
然后检测S是否小于0,如果小于0则唤醒等待使用S资源的其它进程。
三、环境配置
1.安装ubuntu
(1)下载系统镜像,ubuntu-16.04.1-desktop-amd64.iso
(2)制作启动U盘,使用Ultraiso软件将系统镜像写入U盘
(3)开机进入BIOS界面,从U盘启动。
(4)对磁盘分区,等待安装结束。
(5)设置root密码,sudopasswdroot命令后输入两遍密码。
2.熟悉ubuntu的使用
常用命令:
(1)su命令,切换用户
(2)pwd命令,打印当前工作目录的绝对路径
(3)ls命令,打印当前目录下的文件
(4)cd命令,切换工作目录
(5)mv命令,移动文件或目录
(6)rm命令,删除文件或目录
(7)shutdown命令,关闭计算机
(8)reboot命令,重启电脑
(9)tar命令,解压命令
3.安装vim编辑器
在终端下运行apt-getinstall–yvim即可。
安装结束后,输入vim命令,显示如下图就说明安装成功:
Figure1安装vim后输入vim显示的结果
4.源码安装python3.5.2
因为linux内置的python的版本为2.7.5,所以为了程序设计的方便,使用3.5.2版本的。
终端下输入python即可进入python交互模式。
安装前:
Figure2内置python运行结果
安装步骤:
(1)进入下载目录,tar–zxvfPython-3.5.2.tar.gz解压到当前目录下
(2)进入解压目录,cdPython-3.5.2
(3)验证系统配置,./configure
(4)编译和安装,make&
&
makeinstall
(5)建立软链接,在/usr/bin目录下生成python3的软链接文件
安装结果:
Figure3python3安装结果
四、设计思路
1.题目分析:
father、mather、son、daughter是四个线程或进程。
盘子plate是它们共享的变量,对盘子的操作要互斥。
Father和daughter要对apple同步。
Mother和son要对orange同步。
2.伪代码:
father:
while(True):
p(empty)
p(mutex)
putapple
v(mutex)
v(apple)
mother:
p(empty)
p(mutex)
putorange
v(mutex)
v(orange)
son:
p(orange)
getorange
v(empty)
daughter:
p(apple)
getapple
五、代码实现
1.线程实现
(1)原理
threading.py模块提供了对线程的操作。
创建线程threading.Thread(target,args),target是要运行的函数,args是函数所需的参数。
创建信号量threading.Semaphore(value),value是信号量的初始值。
acquire()信号量-1,当为0时,阻塞当前线程。
release()信号量+1,大于0,唤醒等待此信号量的一个线程。
创建互斥锁,threading.Lock(),acquire()加锁,release()解锁。
(2)变量
定义list类型的apples_basket存放所有的苹果
定义list类型的oranges_basket存放所有的橘子
定义list类型的plate当做水果盘,可以放入苹果和橘子
定义方法father,用于将苹果放入水果盘,也就是把apples_basket的一个苹果,放入plate列表中。
并打印相关信息。
定义方法mather,用于将苹果放入水果盘,也就是把oranges_basket的一个橘子,放入plate列表中。
定义方法son,用于从水果盘取出一个橘子,也就是把plate的一个橘子,拿出来,并打印相关信息。
定义方法daughter,用于从水果盘取出一个苹果,也就是把plate的一个苹果,拿出来,并打印相关信息。
(3)代码
importrandom
importthreading
importtime
empty=threading.Semaphore(5)#盘子的容量
apple=threading.Semaphore(0)#同步苹果的信号量
orange=threading.Semaphore(0)#同步橘子的信号量
mutex=threading.Event()#表示四个进程互斥的访问盘子
plate=list()#模拟水果盘
lock=threading.Lock()#plate互斥锁
mutex.set()#设置为True
deffather(basket):
globalempty,mutex,lock,apple
whilelen(basket)!
=0:
#当苹果篮子中没有苹果,则终止
#1.p(empty)
empty.acquire()#将容量empty减去1
#2.p(mutex)
mutex.clear()#mutex设置为False其它线程将等待
#3.putapple
iflock.acquire():
temp=basket.pop()
plate.append(temp)#从苹果篮子里拿出一个苹果放入水果盘
print('
->
fatherputanapple({0})intoplate.'
.format(temp))
currentplate='
plate)
lock.release()
#4.v(mutex)
mutex.set()#mutex设置为True,其它线程可以使用
#5.v(apple)
apple.release()
time.sleep(random.random())
defmother(basket):
globalempty,mutex,lock,orange
#当橘子篮子中没有橘子,则终止
#3.put(orange)
plate.append(temp)
motherputanorange({0})intoplate.'
#5.v(orange)
orange.release()
defson(count):
foriinrange(count):
#1.p(orange)
orange.acquire()#orange-1
#3.getorange
forfruitinplate:
iffruit.startswith('
Orange'
):
temp=fruit
plate.remove(fruit)
break
sontakeanorange({0})fromplate.'
#5.v(empty)
empty.release()#将empty+1
defdaughter(count):
foriinrange(count)