Carlo
Carlo

Reputation: 1578

Program working with multithreading, hangs when using multiprocessing

I'm practicing with multithreading and multiprocessing, and I tried to implement the same program using both approaches.
The idea is to have two parallel threads/processes: one reading frames from a webcam and sending them to a queue, the other ones retrieves them and displays them.

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, args=(source, 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, args=(self.camera_queue,))
        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)

The weird thing is that if I use threads for the two separate tasks, everything works fine. On the other hand, if I assign them to different processes, the one supposed to be showing frames (Camera_Display) hangs...I get the output:

Frame: 0
Cam Loaded...

so, the print("Here") line does not get executed, and the process hangs during the first iteration of the while loop. I'm assuming both approaches should be usable for this problem, I don't understand what is going wrong when I use multiprocessing.

Upvotes: 0

Views: 509

Answers (1)

xxa
xxa

Reputation: 1318

It is not enough to replace Threads by Processes, you also have to use multiprocessing.Queue instead of queue.Queue. The latter is meant for Threads by default.

https://docs.python.org/3/library/multiprocessing.html#exchanging-objects-between-processes

Upvotes: 0

Related Questions