Reputation: 1578
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
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