问题描述
我正在使用多线程和多处理,并且尝试使用两种方法来实现相同的程序。
这个想法是有两个并行的线程/进程:一个从网络摄像头读取帧并将其发送到队列,另一个从中检索并显示它们。
import json
import queue,threading
from queue import Queue
import trigger_events
import multiprocessing as mp
import cv2
class system_manager():
def __init__(self,source):
## camera reader
self.camera_queue = queue.Queue(maxsize=1)
# self.cam_read = threading.Thread(target=Camera_Reader,args=(source,self.camera_queue))
self.cam_read = mp.Process(target=Camera_Reader,self.camera_queue))
self.cam_read.daemon = True
self.cam_read.start()
## module for managing triggers (user/mug position)
# self.cam_display = threading.Thread(target=Camera_display,args=(self.camera_queue,))
self.cam_display = mp.Process(target=Camera_display,))
self.cam_display.daemon = True
self.cam_display.start()
def Camera_Reader(source,camera_queue):
print("Cam Loading...")
cap=cv2.VideoCapture(source)
print("Cam Loaded...")
while(True):
# print(f"frame: {counter}")
ret,frame = cap.read()
# counter += 1
camera_queue.put(frame)
def Camera_display(camera_queue):
counter_frame = 0
while(True):
try:
print(f"\nFrame: {counter_frame}")
frame = camera_queue.get()
key = cv2.waitKey(1)
if (key == ord('q')):
break
print("Here")
counter_frame += 1
cv2.imshow("Frame",frame)
except camera_queue.Empty:
print("nothing in queue!!!")
cv2.destroyAllWindows()
if __name__ == "__main__":
SM = system_manager(source=0)
奇怪的是,如果我将线程用于两个单独的任务,则一切正常。 另一方面,如果我将它们分配给不同的进程,则应该显示帧(Camera_display)的那个挂起...我得到输出:
Frame: 0
Cam Loaded...
因此,不会执行print(“ Here”)行,并且该过程在while循环的第一次迭代期间挂起。 我以为这两种方法都应该适用于此问题,我不知道使用多处理时出了什么问题。
解决方法
仅通过进程替换线程是不够的,还必须使用multiprocessing.Queue
而不是queue.Queue
。后者默认情况下用于线程。
https://docs.python.org/3/library/multiprocessing.html#exchanging-objects-between-processes