【发布时间】:2018-03-07 23:29:47
【问题描述】:
我正在用tkinter 编写一个GUI,它使用cv2 从计算机摄像头中提取视频流。为此,Thread 使用 while 循环重新加载图像。
我一直在使用Locks,所以Threads(主要和辅助)都按预期结束了他们的进程。但是,由于我无法识别的死锁,我无法做到这一点。
代码如下:
import tkinter as tk
import cv2
import time
import sys
import threading
from PIL import ImageTk, Image
class Application:
gui_root = None
gui_panel = None
frame = None
video_capture = None
stop_event = None
thread = None
thread_lock = None
def __init__(self):
self.gui_root = tk.Tk()
self.gui_root.geometry("640x480")
self.gui_root.resizable(False, False)
self.video_capture = cv2.VideoCapture(0)
self.stop_event = threading.Event()
self.thread_lock = threading.Lock()
self.thread = threading.Thread(target=self.load_frame, args=())
self.thread.start()
self.gui_root.wm_protocol("WM_DELETE_WINDOW", self.on_close)
def start(self):
self.gui_root.mainloop()
def load_frame(self):
print('Starting load_frame')
while self.thread_lock.acquire() and not self.stop_event.is_set():
_, self.frame = self.video_capture.read()
self.frame = cv2.resize(self.frame, (640, 480))
c_image = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
c_image_tk = ImageTk.PhotoImage(Image.fromarray(c_image))
if self.gui_panel is None:
self.gui_panel = tk.Label(image=c_image_tk)
self.gui_panel.place(width=640, height=480, x=0, y=0)
else:
self.gui_panel.configure(image=c_image_tk)
self.thread_lock.release()
print("End of while")
self.thread_lock.release()
print('End of Process 2')
def on_close(self):
self.stop_event.set()
print("Event set")
with self.thread_lock:
self.video_capture.release()
self.gui_root.destroy()
app = Application()
app.start()
【问题讨论】:
-
一般来说,你只能在主线程上做 Tk 的东西。如果您执行诸如在工作线程上创建新标签之类的操作,具体取决于您的平台、代码的确切细节、是否是星期二等,它可能会工作、什么也不做、崩溃、挂起或挂起,直到主线程得到运行事件循环的机会。最后一个会导致字面上的死锁,如果你不是很精确,其他一些可能看起来像死锁。
标签: python multithreading tkinter locking deadlock