首页 > 解决方案 > 在函数内启动线程

问题描述

我试图用这样的结构执行代码:

import things
...
class MyThreadRead(Thread):
    ...
    def run(self):
        global cap
        global frame_resized
        global netMain
        ...
        ret, frame = cap.read()
        frame_resized = cv2.resize(...)

...
...
def YOLO():
    ...
    global frame_resized
    global cap
    ...
    cap = cv2.VideoCapture(...)
    ...
    while True:
        ...
        readFrameThread.start()
        detections = detect(a, b, frame_resized, c)
        ...
    readFrameThread.join()
...
...
if __name__== "__main__":
    readFrameThread = MyThreadRead(1)
    YOLO()

当我执行此脚本时,我在 YOLO 函数内的函数检测行中收到此错误:

NameError: global name ´frame_resized´ is not defined

我应该在哪里声明全局变量?在 YOLO 函数内部还是外部?

标签: pythonpython-2.7global-variablespython-multithreading

解决方案


您应该像这样在全局级别定义它

if __name__== "__main__":
    frame_resized = None
    readFrameThread = MyThreadRead(1)
    YOLO()

但更好的是完全避免使用全局变量。有很多方法可以做到这一点,一种是创建数据容器并将其传递给各方。它看起来像这样:

class Container:
    def __init__(self):
        self.cap = None
        self.frame_resized = None
        self.netMain  = None

class MyThreadRead(Thread):
    def __init__(self, container):
        self.container = container

    def run(self):
        ret, frame = self.container.cap.read()
        self.container.frame_resized = cv2.resize(...)

def YOLO(container, trd):
    container.cap = cv2.VideoCapture(...)
    ...
    while True:
        ...
        readFrameThread.start()
        detections = detect(a, b, container.frame_resized, c)
        ...
    trd.join()

if __name__== "__main__":
    container = Container()
    readFrameThread = MyThreadRead(1, container)
    YOLO(container, readFrameThread)

在选择如何实现容器时,不要忘记,namedtuples它们是只读的,不适合您的情况。


推荐阅读