【问题标题】:Python threading: wait for thread to stop then execute functionPython线程:等待线程停止然后执行函数
【发布时间】:2020-03-04 19:36:58
【问题描述】:

我试图在我的线程完成后运行一个函数,但该函数没有被调用。代码结构:

class():

    def functiontocall()  # uses data calculated in thread for plotting. only works when thread is complete
        do something with self.A

    def watchthread():
        thread()
        functiontocall()
        # since this function depends on variable A, it throws an error.
        # I tried: if thread.join == True: functiontocall but this did not call the function.

    def thread():
        def run():
            pythoncom.CoInitialize()
            --- do stuff --
            for i in 1000:
                thousands of calculations while updating state in GUI ---
            A = result
            self.A = A
        thread = threading.Thread(target=run)
        thread.start()

注意:为简单起见,我删除了“self”。

thread.join 应该告诉我线程何时完成但由于某种原因我仍然无法运行函数调用。

这是一种组织线程的坏方法吗?

编辑:我可以在线程完成后调用该函数,但在线程运行时我无法访问变量。例如我的 GUI 中进度条的进度为 0-100%。当我使用时:

def watchthread():
    thread()
    thread.join()
    functiontocall()

我无法在我的 GUI 中更新线程的状态。它只是等到计算完成然后运行 ​​functiontocall()。

【问题讨论】:

    标签: python python-multithreading


    【解决方案1】:

    因为您正在使用线程,一旦线程启动,Python 将继续执行下一步操作,除非您要求,否则它不会等待线程完成。

    使用您的代码,如果您想在继续之前等待线程函数完成,那么听起来您不需要线程,正常的函数将运行,完成,然后 Python 将继续运行 functiontocall()

    如果您需要使用示例中没有遇到的线程,那么我建议您使用 thread.join()

    threads = []  # list to hold threads if you have more than one
    t = threading.Thread(target=run)
    threads.append(t)
    
    for thread in threads:  # wait for all threads to finish
        thread.join() 
    
    functiontocall()  # will only run after all threads are done
    

    再次,我建议您重新考虑一下线程是否是您需要在此处使用的,因为它似乎并不明显。

    要根据新信息更新此答案,这可能是您希望变量可访问的方式。在这种情况下,线程都会更新您的类变量 A,您的 GUI 更新函数也会定期读取它并更新您的 GUI。

    class ThisClass():
    
        def __init__(self):
            self.A = 0
    
        def function_to_call(self):
            while self.A != 100:  # assuming this is a progress bar to 100%
                # update in GUI
    
        def run(self):
            # does calculations
            with lock: # to prevent issues with threads accessing variable at the same time
                self.A += calculations
    
        def progress(self):
            threads = []  # list to hold threads if you have more than one
            t = threading.Thread(target=run)
            threads.append(t)
    
            f = threading.Thread(target=self.function_to_call)
            threads.append(f)
    
            for thread in threads:
                thread.start()
    
            for thread in threads:  # wait for all threads to finish
                thread.join()
    

    【讨论】:

    • 感谢您的回答。我需要线程,因为我正在运行多个计算并且我正在更新 GUI 中的进度。我已经更新了我的问题。
    • 你不能真正从线程返回值,但是既然你使用的是一个类,为什么不尝试将值存储在一个变量中,然后每个线程都可以更新呢?例如 self.A = None 每个线程都可以使用锁: self.A = x
    • 对不起。是的,我使用 return 来简化。我确实分配了变量。
    • 希望这个问题现在更有意义了?
    • 更新了我的答案以更好地展示这一点。线程可以更新您的类变量,然后您的 GUI 更新函数会在 GUI 中读取和更新该变量
    猜你喜欢
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    • 2020-04-12
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多