#opencv #python-multiprocessing #python-multithreading
#opencv #python-многопроцессорная обработка #python-многопоточность
Вопрос:
Я практикуюсь с многопоточностью и многопроцессорностью, и я попытался реализовать одну и ту же программу, используя оба подхода.
Идея состоит в том, чтобы иметь два параллельных потока / процесса: один считывает кадры с веб-камеры и отправляет их в очередь, другие извлекают их и отображают.
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(«Здесь») не выполняется, и процесс зависает во время первой итерации цикла while.
Я предполагаю, что оба подхода должны использоваться для решения этой проблемы, я не понимаю, что происходит не так, когда я использую многопроцессорную обработку.
Ответ №1:
Недостаточно заменить потоки процессами, вы также должны использовать multiprocessing.Queue
вместо queue.Queue
. Последняя предназначена для потоков по умолчанию.
https://docs.python.org/3/library/multiprocessing.html#exchanging-objects-between-processes
Комментарии:
1. Это не было причиной моей проблемы, я решил ее с помощью set_start_method(«spawn»). Однако, когда процессы, наконец, начали выполняться, мне пришлось использовать mp.Queue, так что вы в основном решили следующую проблему в очереди, спасибо! 😉
2. Я не думаю, что изменение метода запуска решило проблему связи, но, конечно, это хорошая новость, что она работает сейчас.
3. Извините, возможно, я неправильно объяснил себя. Первоначальная проблема заключалась в том, что процессы даже не запускались, что было исправлено с помощью spawn в качестве метода запуска. Как только я это сделал, я получил другую ошибку, связанную с использованием очередей (TypeError: не удается определить _thread . блокировка объектов)… Я решил эту последнюю проблему с помощью многопроцессорной обработки. Очередь вместо очереди. Очередь
4. Вы написали, что был вывод из обоих процессов, но
print('Here')
не был выполнен. Таким образом, процессы, должно быть, начались, возникла проблема связи с использованиемqueue.Queue
вместоmultiprocessing.Queue
.5. К сожалению, в разделе импорта была ошибка, как только я исправил это и использовал mp.Queues(), все прошло нормально, даже без запуска процессов. В моей (частичной) защите минимальный пример, который я опубликовал, был слишком minimal…in в реальной ситуации мне все еще нужно использовать set_start_method(«spawn»), чтобы запустить процессы. Я подозреваю, что это может быть связано с одним из процессов, использующих библиотеку глубокого обучения, которая уже реализует многопроцессорную обработку … может быть, это портит весь механизм? Мне нужно будет разобраться с этим .. в любом случае, спасибо!