进程同步程序设计---吃水果问题
吃水果问题
桌子上有一只盘子,最多可容纳两个水果,每次只能放入或者取出一个水果。爸爸专门向盘子中放苹果,妈妈专门向盘子中放橘子,儿子专门等待吃盘子中的橘子,女儿专门等吃盘子中的苹果。试编程实现爸爸、妈妈、儿子、女儿四个人之间的同步。
要求:
(1)水果、盘子均通过导入图片来实现可视化;
(2)放水果、拿水果均有动画显示,包括把水果拿到手上去放、放完空手回来等均通过的动画予以展示;
(3)执行顺序由并发控制机制决定,而非通过延时实现;
(4)要求界面美观、动作流畅。
界面运行截图
运行结果:
代码框架
以P,V操作的框架为基础,掌握在python中,P,V操作如何转变为代码,多进程并行操作如何执行,以及各种相应的锁的运用。
import threading,time,pygame
def daughter_eat(name):
global num, capacity,apple,orange
while True:
#P,此操作减少信号量的内部变量, 如果此变量的值非负, 那么分配该资源的权限. 如果是负值, 那么线程被挂起, 直到有其他的线程释放资源.
#判断桌子上是否有苹果,有则可以执行,否则此进程被挂起不能执行,直到变量值大于0,执行的同时拿起了一个苹果
apple_lock.acquire()
#V,信号量的内部变量增加, 在信号量等待队列中排在最前面的线程会拿到共享资源的权限.
#释放一个进程,代表桌子上允许放一个水果
num_lock.release()
#互斥,不允许其他线程操作
mutex.acquire()
for i in range(50):
screen.blit(background, (0, 0))
if i >=45:
if num == 2:
if apple == 2:
blitOne(appleim)
elif orange == 1:
blitOne(orangeim)
elif num == 1:
pass
# if apple == 1:
# pass
blitPerson()
screen.blit(daughter_hand, (490 - i, 350 - i))
pygame.display.update()
apple -= 1
num -= 1
print(name, "从桌子上拿走一个苹果")
print("现在桌子上还有" str(apple) "苹果" str(orange) "橘子")
#释放互斥,允许下一个进程进行
mutex.release()
time.sleep(3)
def son_eat(name):
global num, capacity, apple, orange
while True:
# 判断桌子上是否有橘子,有则可以执行,否则此进程被挂起不能执行,直到变量值大于0,执行的同时拿起了一个橘子
orange_lock.acquire()
# 释放一个进程,代表桌子上允许放一个水果
num_lock.release()
# 互斥,不允许其他进程操作
mutex.acquire()
for i in range(50):
screen.blit(background, (0, 0))
if i >= 45:
if num == 2:
if apple == 1:
blitTwo(appleim)
elif apple == 0:
blitTwo(orangeim)
elif num == 1:
pass
blitPerson()
screen.blit(son_hand, (170 - i, 390 i))
pygame.display.update()
orange -= 1
num -= 1
print(name, "从桌子上拿走一个橘子")
print("现在桌子上还有" str(apple) "苹果" str(orange) "橘子")
mutex.release()
time.sleep(3)
def father_put(name, fruit):
global num, capacity, apple, orange
while True:
num_lock.acquire()
apple_lock.release()
mutex.acquire()
print(name, "把", fruit, "放在盘子里面")
for i in range(50):
screen.blit(background, (0, 0))
if i >= 45:
if num == 0:
blitOne(appleim)
elif num == 1:
if apple == 1:
blitOne(appleim)
blitTwo(appleim)
else:
blitOne(orangeim)
blitTwo(appleim)
blitPerson()
screen.blit(dad_hand, (140 i, 140 i))
#更新部分软件界面显示
pygame.display.update()
apple = 1
num = 1
print("在爸爸放苹果之后,桌子上苹果的数量: " str(apple) " 桌子上橘子的数量: " str(orange))
mutex.release()
#使放水果速度大于拿水果速度,不会卡顿
time.sleep(2)
def mother_put(name, fruit):
global num, capacity, apple, orange
while True:
#给是否能放水果上锁
num_lock.acquire()
#放橘子解锁
orange_lock.release()
#控制只有一个进程运行,不允许其他进程运行,达到互斥
mutex.acquire()
print(name, "把", fruit, "放在盘子里面")
for i in range(50):
screen.blit(background, (0, 0))
if i >= 45:
if num == 0:
blitOne(orangeim)
elif num == 1:
if orange == 1:
blitOne(orangeim)
blitTwo(orangeim)
else:
blitOne(appleim)
blitTwo(orangeim)
blitPerson()
screen.blit(mom_hand, (510 - i, 140 i))
pygame.display.update()
orange = 1
num = 1
print("在妈妈放橘子之后,桌子上苹果的数量: " str(apple) " 桌子上橘子的数量: " str(orange))
# 互斥效果解除,下一个进程可执行
mutex.release()
time.sleep(2)
def blitOne(fruit):
screen.blit(fruit, one_size)
blitPerson()
def blitTwo(fruit):
screen.blit(fruit, two_size)
blitPerson()
def blitPerson():
screen.blit(father, dad_size)
screen.blit(mom, mom_size)
screen.blit(son, son_size)
screen.blit(daughter, daughter_size)
if __name__ == "__main__":
background_image_filename = 'E:\python代码\picture\Table.png'
apple_image_filename = 'E:\python代码\picture\Apple.png'
orange_image_filename = 'E:\python代码\picture\orange1.png'
mom_image_filename = 'E:\python代码\picture\Mom.png'
father_image_filename = 'E:\python代码\picture\Father.png'
son_image_filename = 'E:\python代码\picture\Son.png'
daughter_image_filename = 'E:\python代码\picture\Daughter.png'
dad_hand_image_filename = 'E:\python代码\picture\Hand1.png'
mom_hand_image_filename = 'E:\python代码\picture\Hand1.png'
son_hand_image_filename = 'E:\python代码\picture\Hand.png'
daughter_hand_image_filename = 'E:\python代码\picture\Hand.png'
# 初始化pygame
pygame.init()
# 所有相应位置
one_size = (200, 300)
two_size = (350, 300)
dad_size = (10, 10)
mom_size = (500, 10)
son_size = (10, 450)
daughter_size = (540, 450)
dad_hand_size = (80, 45)
mom_hand_size = (480, 110)
screenSize = (650, 651)
# 创建窗口
screen = pygame.display.set_mode(screenSize, 0)
# 设置标题
pygame.display.set_caption('吃水果进程')
# 加载图片并转换, 从文件加载新图片,创建一个新的 Surface 对象
background = pygame.image.load(background_image_filename)
appleim = pygame.image.load(apple_image_filename)
orangeim = pygame.image.load(orange_image_filename)
mom = pygame.image.load(mom_image_filename)
father = pygame.image.load(father_image_filename)
son = pygame.image.load(son_image_filename)
daughter = pygame.image.load(daughter_image_filename)
dad_hand = pygame.image.load(dad_hand_image_filename)
mom_hand = pygame.image.load(mom_hand_image_filename)
son_hand = pygame.image.load(son_hand_image_filename)
daughter_hand = pygame.image.load(daughter_hand_image_filename)
#当打印结果是交替打印时,但是如果需求是需要打印完一个线程的内容后,
# 再去打印另一个线程的内容,就需要用到锁。不加锁打印结果:加了睡眠时间,所以每隔1秒会交替打印出a、b值
mutex = threading.Lock()
# 最大容量
capacity = 2
# 当前个数
num = 0
# 苹果个数
apple = 0
# 橘子个数
orange = 0
apple_lock = threading.Semaphore(0)#0个进程
orange_lock = threading.Semaphore(0)
#因为桌子上最多只能放两个水果最少不放水果,对应的最多也只能拿两个水果,最少不拿水果,所以此进程数是2而不是4
num_lock = threading.Semaphore(2)#2个进程
#创建 Thread 对象,然后让它们运行,每个 Thread 对象代表一个进程,在每个线程中我们可以让程序处理不同的任务
mother_thread = threading.Thread(target=mother_put, args=["妈妈", "橘子"])
father_thread = threading.Thread(target=father_put, args=["爸爸", "苹果"])
son_thread = threading.Thread(target=son_eat, args=["儿子"])
daughter_thread = threading.Thread(target=daughter_eat, args=["女儿"])
#启动 Thread 对象
mother_thread.start()
time.sleep(1)
father_thread.start()
time.sleep(1)
son_thread.start()
time.sleep(2)
daughter_thread.start()
time.sleep(2)
图片从阿里矢量图标获取,总共有4个进程,因为每次只能进行一种操作,所以这四个进程都互斥,根据threading.Lock()与threading.Semaphore(2)的结合实现多进程运行且避免死锁的情况发生,通过time.sleep(2)造成延时效果,同时start()函数只能执行一次,不能手动强制停止,否则进程退出并行操作不再执行。
总结
用python语言来体现进程的运行比较直接简洁,通过pygame包引实现窗口的展示与动画,通过threading包引实现多进程并行操作。
如有错误,敬请指正。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggefcf
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13