Python 队列(Queue) Demo

Python的多线程有个队列模块Queue
这个模块就相当于创建一个线程池。举一个例子说明。一下这个Queue,比如我每天都去的吃的乔晨粗粮包子店。假如这个包子店的锅炉一次只能蒸100个包子,那就意味着面点师傅只要做满了100个就没办法做了,等着消费者来将里面消费到一定程度之后重新开始做。
运用到Python就是这个Queue就是那个锅炉,容器。将线程生产出来的数据放到这个容器当中,通过queue.put()将数据放到容器中。,先进先出,然后消费者从这个容器中拿数据,queue.get()获取数据

队列实现生产者消费者模型。
这个模型大概就是有生产者生产包子,生产的包子放到Quque当中,消费者再从Queue当中取包子。

import threading
import time


# 生产者函数
def producers(name, que):
    while True:
        if q.qsize < 10 
            # put方法用于往队列放数据
            que.put('包子')
            print u'%s:生产了一个包子' % name
        time.sleep(random.randrange(5))

def consumers(name, que):
    while True:
        try:
            #get 方法取出数据, get_nowait 如果队列中没有数据则就报错
            que.get_nowait('包子')
            print u'%s: 消费了一个包子' %s name
        except Exception:
            print u'没有包子了'
        time.sleep(random.randrange(3))

q = Que.Que()
# 使用两个线程生产
p1 = threading.Thread(target=producers, args=(u'厨师1', q))
p2 = thread.Thread(target=producers, args=(u'厨师2', q))
p1.start()
p2.start()
# 两个线程是消费者
c1 = thread.Thread(target=consumers, args=(u'消费者1', q))
c1 = thread.Thread(target=consumers, args=(u'消费者2', q))
c1.start()
c1.start()
可以考虑使用多线程来优化程序,将图像采集和画面显示的任务放到两个不同的线程中执行,避免两个任务之间的阻塞和竞争。具体实现可以按照以下步骤: 1. 创建两个线程,一个用于采集图像数据,一个用于显示图像数据。 2. 采集线程中,使用一个循环不断读取摄像头采集到的图像数据,并将其放入队列中。 3. 显示线程中,从队列中获取图像数据,进行处理和显示,并在一定时间后再次获取队列中的数据进行更新。 4. 在程序运行过程中,可以通过控制标志位的值来控制线程的开启和关闭。 下面是一个使用多线程进行优化的示例代码: ``` import threading import cv2 import tkinter as tk from queue import Queue from PIL import Image, ImageTk class Camera(): def __init__(self, top): self.top = top self.h = int(data_demo.window_height // 1.5) self.w = int(data_demo.window_width // 1.74) self.canvas2 = tk.Canvas(self.top, bg='LightSkyBlue', width=self.w, height=self.h, highlightthickness=2, highlightbackground='Black') self.canvas2.place(relx=0.0, rely=0.032) self.label = tk.Label(self.canvas2, text='摄像头显示区!', font=("黑体", 25), width=15, height=1) self.label.place(relx=0.32, rely=0.50, anchor='nw') self.queue = Queue() # 创建一个队列 self.bool = False # 控制线程开启和关闭的标志位 def Firing_run(self, button_id): self.bool = True self.label.destroy() self.cap = cv2.VideoCapture(0) t1 = threading.Thread(target=self.capture_image) t2 = threading.Thread(target=self.show_image) t1.start() t2.start() button_id.config(text='关闭摄像头', command=lambda: self.Cease_stop(button_id)) def Cease_stop(self, button_id): self.bool = False button_id.config(text='打开摄像头', command=lambda: self.Firing_run(button_id)) def capture_image(self): while self.bool: ref, frame = self.cap.read() if ref: self.queue.put(frame) def show_image(self): while self.bool: if not self.queue.empty(): frame = self.queue.get() image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image1 = Image.fromarray(image) image2 = image1.resize((self.w, self.h), Image.ANTIALIAS) photo = ImageTk.PhotoImage(image=image2) self.canvas2.create_image(0, 0, image=photo, anchor=tk.NW) self.canvas2.update() else: continue self.canvas2.after(15) ``` 在上面的代码中,我们创建了两个线程,一个用于采集图像数据(capture_image函数),一个用于显示图像数据(show_image函数)。通过队列来进行线程间通信,采集线程从摄像头中读取图像数据,将其放入队列中;显示线程从队列中获取图像数据,并将其进行处理和显示。同时,我们使用了标志位来控制线程的开启和关闭。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值