使用多线程的程序,在使用多处理时挂起

问题描述

我正在使用多线程和多处理,并且尝试使用两种方法来实现相同的程序。
这个想法是有两个并行的线程/进程:一个从网络摄像头读取帧并将其发送到队列,另一个从中检索并显示它们。

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