python Queue.Queue 和 multiprocessing.Queue 之间的差异
Differences between python Queue.Queue and multiprocessing.Queue
当我使用来自多处理模块(Python 2.7 on Windows)的队列代替 Queue.Queue.
时,我的程序没有完全关闭
最终我想使用 multiprocessing.Process 处理 imgbuffer 中的帧,然后使用第二个队列拉回显示数据。这还行不通 - 似乎 Process.start() 什么都不做 - 但由于我在调试多处理代码时遇到困难,我想我会削减我拥有的最简单的代码,看看是否有问题任何人都知道接下来要尝试什么。
import sys
from PySide import QtGui, QtCore
import cv2
import time, datetime
import multiprocessing
import Queue #needed separately for the Empty exception
def imageOpenCv2ToQImage(cv_img):
height, width, bytesPerComponent = cv_img.shape
bytesPerLine = bytesPerComponent * width;
cv2.cvtColor(cv_img, cv2.cv.CV_BGR2RGB, cv_img)
return QtGui.QImage(cv_img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)
class VideoWidget(QtGui.QLabel):
def __init__(self):
super(VideoWidget, self).__init__()
self.imgbuffer = multiprocessing.Queue()
############################################
# hangs on quit using multiprocessing.Queue
# works fine when I use Queue.Queue
#########################################
self.camera = cv2.VideoCapture(1) # camera ID depends on system: 0, 1, etc
self.setGeometry(100, 100, 640, 480)
self.setScaledContents(True)
target_FPS = 30.0
self.camera_timer = QtCore.QTimer()
self.camera_timer.timeout.connect(self.on_camera_timer)
self.camera_timer.start(1000.0/target_FPS)
target_FPS = 40.0
self.repaint_timer = QtCore.QTimer()
self.repaint_timer.timeout.connect(self.on_repaint_timer)
self.repaint_timer.start(1000.0/target_FPS)
def shutdown(self):
self.camera.release()
def on_camera_timer(self):
hello, cv_img = self.camera.read()
tstamp = datetime.datetime.now()
self.imgbuffer.put((tstamp, cv_img))
def on_repaint_timer(self):
try:
tstamp, cv_img = self.imgbuffer.get(False)
pixmap = QtGui.QPixmap.fromImage(imageOpenCv2ToQImage(cv_img))
self.setPixmap(pixmap)
except Queue.Empty:
pass
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
widget = VideoWidget()
app.aboutToQuit.connect(widget.shutdown)
widget.show()
sys.exit(app.exec_())
我想通了...答案毕竟在文档中:
https://docs.python.org/3/library/multiprocessing.html#pipes-and-queues
特别是:
They differ in that Queue lacks the task_done() and join() methods
introduced into Python 2.5’s queue.Queue class.
就我而言,解决方案似乎是将此添加到关闭代码中:
self.imgbuffer.cancel_join_thread()
当我使用来自多处理模块(Python 2.7 on Windows)的队列代替 Queue.Queue.
时,我的程序没有完全关闭最终我想使用 multiprocessing.Process 处理 imgbuffer 中的帧,然后使用第二个队列拉回显示数据。这还行不通 - 似乎 Process.start() 什么都不做 - 但由于我在调试多处理代码时遇到困难,我想我会削减我拥有的最简单的代码,看看是否有问题任何人都知道接下来要尝试什么。
import sys
from PySide import QtGui, QtCore
import cv2
import time, datetime
import multiprocessing
import Queue #needed separately for the Empty exception
def imageOpenCv2ToQImage(cv_img):
height, width, bytesPerComponent = cv_img.shape
bytesPerLine = bytesPerComponent * width;
cv2.cvtColor(cv_img, cv2.cv.CV_BGR2RGB, cv_img)
return QtGui.QImage(cv_img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888)
class VideoWidget(QtGui.QLabel):
def __init__(self):
super(VideoWidget, self).__init__()
self.imgbuffer = multiprocessing.Queue()
############################################
# hangs on quit using multiprocessing.Queue
# works fine when I use Queue.Queue
#########################################
self.camera = cv2.VideoCapture(1) # camera ID depends on system: 0, 1, etc
self.setGeometry(100, 100, 640, 480)
self.setScaledContents(True)
target_FPS = 30.0
self.camera_timer = QtCore.QTimer()
self.camera_timer.timeout.connect(self.on_camera_timer)
self.camera_timer.start(1000.0/target_FPS)
target_FPS = 40.0
self.repaint_timer = QtCore.QTimer()
self.repaint_timer.timeout.connect(self.on_repaint_timer)
self.repaint_timer.start(1000.0/target_FPS)
def shutdown(self):
self.camera.release()
def on_camera_timer(self):
hello, cv_img = self.camera.read()
tstamp = datetime.datetime.now()
self.imgbuffer.put((tstamp, cv_img))
def on_repaint_timer(self):
try:
tstamp, cv_img = self.imgbuffer.get(False)
pixmap = QtGui.QPixmap.fromImage(imageOpenCv2ToQImage(cv_img))
self.setPixmap(pixmap)
except Queue.Empty:
pass
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
widget = VideoWidget()
app.aboutToQuit.connect(widget.shutdown)
widget.show()
sys.exit(app.exec_())
我想通了...答案毕竟在文档中:
https://docs.python.org/3/library/multiprocessing.html#pipes-and-queues
特别是:
They differ in that Queue lacks the task_done() and join() methods introduced into Python 2.5’s queue.Queue class.
就我而言,解决方案似乎是将此添加到关闭代码中:
self.imgbuffer.cancel_join_thread()