模拟内容要求
利用C语言或JAVA语言或C++语言(手段不限),验证生产者与消费问题的过程。
一、效果截图
二、代码实现
from tkinter import *
from PIL import Image, ImageTk
import threading
import time
from queue import Queue
class Application(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
photo = Image.open("images/apple.png").resize((32, 32))
self.img = ImageTk.PhotoImage(photo)
self.x1 = 20
self.x2 = 20
self.createWidget()
def createWidget(self):
"""创建组件"""
# 1.开始按钮
self.b_start = Button(root, text="开始", width=10, height=1, command=self.start)
self.b_start.place(relx=0.45, rely=0.11)
# 2.生产者进程
self.canvas1 = Canvas(root, width=210, height=50, bg="white")
self.canvas1.place(relx=0.1, rely=0.08)
self.canvas1.create_text(105, 25, text="生产者进程")
self.b_produce = Button(root, text="开始生产", width=10, height=1, state="disabled", command=self.pro)
self.b_produce.place(relx=0.1, rely=0.3)
self.b_stop1 = Button(root, text="停止生产", width=10, height=1, state="disabled", command=self.stop1)
self.b_stop1.place(relx=0.235, rely=0.3)
# 3.缓冲器(队列)
self.canvas2 = Canvas(root, width=350, height=80, bg="white")
self.canvas2.place(relx=0.33, rely=0.4)
self.canvas2.create_text(175, 40, text="缓冲器")
# 4.消费者进程
self.canvas3 = Canvas(root, width=210, height=50, bg="white")
self.canvas3.place(relx=0.7, rely=0.6)
self.canvas3.create_text(105, 25, text="消费者进程")
self.b_consume = Button(root, text="开始消费", width=10, height=1, state="disabled", command=self.con)
self.b_consume.place(relx=0.7, rely=0.78)
self.b_stop2 = Button(root, text="停止消费", width=10, height=1, state="disabled", command=self.stop2)
self.b_stop2.place(relx=0.835, rely=0.78)
# 5.图片
self.canvas1.create_image(20, 40, tag="pic1", image=self.img)
self.canvas3.create_image(20, 40, tag="pic2", image=self.img)
def start(self):
"""点击开始按钮"""
self.b_stop1["state"] = "normal" # 停止生产按钮解禁
self.b_consume["state"] = "normal" # 开始消费按钮解禁
self.b_start["state"] = "disabled" # 开始按钮禁用
produce.start() # 开始执行生产者线程
consume.start() # 开始执行消费者线程
# 停止生产
def stop1(self):
self.b_produce["state"] = "normal" # 开始生产按钮解禁
self.b_stop1["state"] = "disabled" # 停止生产按钮禁用
produce.pause() # 将暂停线程的标识设置为False
# 开始生产
def pro(self):
self.b_stop1["state"] = "normal" # 停止生产按钮解禁
self.b_produce["state"] = "disabled" # 开始生产按钮禁用
# 当队列消费品满时 不做任何操作
if q.qsize() == 9:
return
produce.resume() # 将暂停线程的标识设置为True
# 开始消费
def con(self):
self.b_stop2["state"] = "normal"
self.b_consume["state"] = "disabled"
# 当队列没有消费品时 不做任何操作
if q.qsize() == 0:
return
consume.resume() # 将暂停线程的标识设置为True
# 停止消费
def stop2(self):
self.b_consume["state"] = "normal"
self.b_stop2["state"] = "disabled"
consume.pause() # 将暂停线程的标识设置为False
# 渲染缓冲器(队列)的图片
def buffer(self):
size = q.qsize()
self.canvas2.delete("all")
self.canvas2.create_text(175, 40, text="缓冲器")
for i in range(size):
self.canvas2.create_image(20+39*i, 60, image=self.img)
# 自定义生产者线程类
class produceThread(threading.Thread):
def __init__(self):
super().__init__()
self.__flag = threading.Event() # 用于暂停线程的标识 默认为False
self.__flag.set() # 设置为True
def run(self):
while True:
app.canvas1.delete("pic1")
while app.x1 < 250:
app.canvas1.create_image(app.x1, 40, tag="pic1", image=app.img)
app.canvas1.update()
self.__flag.wait() # 为True则立即返回 为False时阻塞直到内部的标识位为True后返回
time.sleep(0.05)
app.canvas1.delete("pic1")
app.x1 += 10
app.x1 = 20
q.put(1)
app.buffer()
# 当可消费的对象溢出的时候
if q.qsize() == 9:
app.canvas1.create_image(app.x1, 40, tag="pic1", image=app.img)
app.stop1()
# 停止线程
def pause(self):
self.__flag.clear() # 设置为False 让线程阻塞
# 执行线程
def resume(self):
self.__flag.set() # 设置为True 让线程停止阻塞
# 自定义消费者线程类
class consumeThread(threading.Thread):
def __init__(self):
super().__init__()
self.__flag = threading.Event() # 用于暂停线程的标识 默认为False
def run(self):
while True:
app.canvas1.delete("pic2")
while app.x2 < 250:
app.canvas3.create_image(app.x2, 40, tag="pic2", image=app.img)
app.canvas3.update()
self.__flag.wait() # 为True则立即返回 为False时阻塞直到内部的标识位为True后返回
time.sleep(0.05)
app.canvas3.delete("pic2")
app.x2 += 10
app.x2 = 20
q.get()
app.buffer()
# 没有可消费的对象的时候
if q.qsize() == 0:
app.canvas3.create_image(app.x2, 40, tag="pic2", image=app.img)
app.stop2()
# 停止线程
def pause(self):
self.__flag.clear() # 设置为False 让线程阻塞
# 执行线程
def resume(self):
self.__flag.set() # 设置为True 让线程停止阻塞
if __name__ == '__main__':
root = Tk()
root.geometry('1000x500+500+200')
root.title('模拟生产者消费者进程')
app = Application(master=root)
q = Queue(maxsize=9)
produce = produceThread()
consume = consumeThread()
produce.setDaemon(True) # 设置线程守护
consume.setDaemon(True) # 设置线程守护
root.mainloop()
说明
根据计算机系统实验要求制作,原创,使用python内置模块tkinter实现,只需要修改里面图片的路径即可