Проблема с потоками Python в OpenCV - PullRequest
1 голос
/ 18 июня 2019

Я использовал threading модуль с OpenCV, я столкнулся со странной проблемой. При использовании потока я не смог запустить камеру снова, чтобы взять видео вход. Я бы взял один кадр, а затем остановиться. Пока не было такой проблемы при использовании multiprocessing модуля. Я не могу понять, что вызывает это странное поведение.

Этот код обобщает проблему, с которой я столкнулся. Программа зависнет при повторном создании потока.

import cv2
import time
import threading

def open_cam():
    count = 0
    cam = cv2.VideoCapture(0)
    while True:
        ret_val, img = cam.read()
        print(ret_val)
        cv2.imshow("Image", img)
        count += 1
        if count == 100:
            break
        if (cv2.waitKey(1) & 0xFF) == ord('q'):
            break
    cv2.destroyAllWindows()



def start_thread():
    print("CREATING THREAD")
    cam_thread = threading.Thread(target=open_cam)
    print("STARTING THREAD")
    cam_thread.start()

start_thread()
time.sleep(5)
start_thread()  

Тем не менее, этот код работает именно так, как я хочу, он использует multiprocessing модуль вместо threading

import cv2
import time
import multiprocessing

def open_cam():
    count = 0   
    cam = cv2.VideoCapture(0)
    while True:
        ret_val, img = cam.read()
        print(ret_val)
        cv2.imshow("Image", img)
        count += 1
        if count == 100:
            break
        if (cv2.waitKey(1) & 0xFF) == ord('q'):
            break
    cv2.destroyAllWindows()



def start_process():
    print("CREATING process")
    cam_process = multiprocessing.Process(target=open_cam)
    print("STARTING process")
    cam_process.start()

start_process()
time.sleep(5)
start_process()

В чем причина проблемы и как ее исправить?

1 Ответ

0 голосов
/ 19 июня 2019

Это вызвано глобальной блокировкой интерпретатора. Потоки разделяют память программы. Чтобы защитить от конфликтов, вызванных изменением одной и той же переменной отдельными потоками, Python блокирует выполнение для определенного потока. Это означает, что в любой момент работает только один поток. Когда процессор простаивает, программа переключается между потоками, что ускоряет работу приложений, связанных с вводом-выводом. В отличие от этого, процессы запускаются одновременно на разных ядрах и не разделяют память.

Когда в вашем коде запускается второй поток, оба потока пытаются получить доступ к одним и тем же переменным. Это вызывает ошибку с потоками, в то время как процессы работают нормально.

Здесь - превосходное и более длинное объяснение.

...