在Python中同时运行依赖线程

在Python中同时运行依赖线程,python,python-3.x,multithreading,python-multithreading,Python,Python 3.x,Multithreading,Python Multithreading,我有两个线程类extract和detect Extract从视频中提取帧并将其存储在文件夹中,Detect从提取帧的文件夹中获取图像并检测对象 但是当我运行下面的代码时,只有摘录有效: global q q = Queue() class extract(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): print("T1"

我有两个线程类extract和detect

Extract从视频中提取帧并将其存储在文件夹中,Detect从提取帧的文件夹中获取图像并检测对象

但是当我运行下面的代码时,只有摘录有效:

global q
q = Queue()

class extract(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        print("T1")
        cam = cv2.VideoCapture(video_name)
        frameNum = 0
        # isCaptured = True
        frameCount = 0
        while True:
            isCapture, frame = cam.read()
            if not isCapture:
                break
            if frameCount % 5 == 0:
                frameNum = frameNum + 1
                fileName = vid + str(frameNum) + '.jpg'
                cv2.imwrite('images/extracted/' + fileName, frame)
                q.put(fileName)
            frameCount += 1
        cam.release()
        cv2.destroyAllWindows()

class detect(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        print("T2")
        #logic to detect objects. 


if __name__ == '__main__':
    thread1 = extract()
    thread1.start()
    thread2 = detect()
    thread2.start()
这只打印T1,不打印T2。 我认为detect可能首先运行,而队列是空的,所以什么也没发生,所以我在队列中添加了虚拟条目,它按照我希望的方式运行

但它只对伪条目运行,对提取函数添加到队列中的条目不起作用。
查找其他问题,但似乎没有一个问题能够解决问题,因此将此贴在此处

您可能也希望将检测逻辑保持在无限循环中

class detect(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        while True: 
        #detect frame
如果是单帧检测。 然后考虑在检测线程中等待。p>
from time import sleep
class detect(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)

        def run(self):
           sleep(120)
           # Detect logic

您可能还希望将检测逻辑保持在无限循环中

class detect(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        while True: 
        #detect frame
如果是单帧检测。 然后考虑在检测线程中等待。p>
from time import sleep
class detect(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)

        def run(self):
           sleep(120)
           # Detect logic

您可以使用
Event()
并让检测线程在执行检测之前等待
Event()
设置,而不是等待硬编码的时间

如果设置了事件,则表示所有任务都已完成。此外,如果有任何任务尚未处理,您还必须关注队列

我已经编写了一个示例代码来演示它是如何工作的,您可以根据需要修改代码

在这里,
extract
需要5秒钟才能将任务添加到队列中,
detect
每1秒检查一次任务。因此,如果提取速度比任何时候都慢,则
detect
将对提取进行处理。当所有任务完成时,detect将跳出循环

import threading
import queue
import time

global q
q = queue.Queue()

class extract(threading.Thread):
    all_tasks_done = threading.Event()
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        counter = 5
        while counter:
            time.sleep(5)
            counter -= 1
            q.put(1)
            print("added a task to queue")
        extract.all_tasks_done.set()



class detect(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        while not extract.all_tasks_done.wait(1) or not q.empty():
            print(q.get())
        print("detection done")
        #logic to detect objects. 


if __name__ == '__main__':
    thread1 = extract()
    thread1.start()
    thread2 = detect()
    thread2.start()
    thread1.join()
    thread2.join()
    print("work done")

您可以使用
Event()
并让检测线程在执行检测之前等待
Event()
设置,而不是等待硬编码的时间

如果设置了事件,则表示所有任务都已完成。此外,如果有任何任务尚未处理,您还必须关注队列

我已经编写了一个示例代码来演示它是如何工作的,您可以根据需要修改代码

在这里,
extract
需要5秒钟才能将任务添加到队列中,
detect
每1秒检查一次任务。因此,如果提取速度比任何时候都慢,则
detect
将对提取进行处理。当所有任务完成时,detect将跳出循环

import threading
import queue
import time

global q
q = queue.Queue()

class extract(threading.Thread):
    all_tasks_done = threading.Event()
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        counter = 5
        while counter:
            time.sleep(5)
            counter -= 1
            q.put(1)
            print("added a task to queue")
        extract.all_tasks_done.set()



class detect(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        while not extract.all_tasks_done.wait(1) or not q.empty():
            print(q.get())
        print("detection done")
        #logic to detect objects. 


if __name__ == '__main__':
    thread1 = extract()
    thread1.start()
    thread2 = detect()
    thread2.start()
    thread1.join()
    thread2.join()
    print("work done")

您的
检测
工作基本上是在
提取
完成其工作后开始的。那你为什么要让它们并行运行呢?我正在做一个实时检测,这就是为什么我需要它们一起运行你的
detect
工作基本上是在
extract
完成工作后开始的。那为什么你想让它们并行运行呢?我正在进行实时检测,这就是为什么我需要它们一起运行的原因。这仍然会提供相同的输出。这仍然会提供相同的输出。在运行的while循环中。运行这个脚本一次,看看它是否能像预期的那样工作:提取并检测到工作否,这并没有给我预期的输出。我使用rabbitmq从extract传递消息,并在detect中检索它。这在运行的while循环中完成了作业。运行这个脚本一次,看看它是否能像预期的那样工作:提取并检测到工作否,这并没有给我预期的输出。我使用rabbitmq从extract传递消息,并在detect中检索它。成功了