使用多线程的程序在使用多处理时挂起
Program working with multithreading, hangs when using multiprocessing
我正在练习多线程和多处理,我尝试使用这两种方法实现相同的程序。
这个想法是有两个并行的threads/processes:一个从网络摄像头读取帧并将它们发送到队列,另一个检索它们并显示它们。
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)
奇怪的是,如果我对两个单独的任务使用线程,一切都会正常进行。
另一方面,如果我将它们分配给不同的进程,应该显示帧 (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
我正在练习多线程和多处理,我尝试使用这两种方法实现相同的程序。
这个想法是有两个并行的threads/processes:一个从网络摄像头读取帧并将它们发送到队列,另一个检索它们并显示它们。
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)
奇怪的是,如果我对两个单独的任务使用线程,一切都会正常进行。 另一方面,如果我将它们分配给不同的进程,应该显示帧 (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