【问题标题】:Python thread.join(timeout) not timing outPython thread.join(超时)没有超时
【发布时间】:2021-01-11 12:36:51
【问题描述】:

我正在使用线程 python 模块。我想执行一个运行用户输入的表达式的函数。我想等待它完成执行或直到达到超时期限。以下代码应在 5 秒后超时,但永远不会超时。

def longFunc():
    # this expression could be entered by the user
    return 45 ** 10 ** 1000
 
thread = threading.Thread(target=longFunc, args=(), daemon=True)
thread.start()
thread.join(5.0)
print("end") # never reaches this point :(

为什么会这样,我该如何解决这个问题?我应该尝试改用多处理吗?

【问题讨论】:

    标签: python multithreading python-multiprocessing python-multithreading


    【解决方案1】:

    我怀疑在这种情况下,您遇到的问题是 join 无法执行,而全局解释器锁由非常长时间运行的计算持有,我相信这将作为单个原子操作发生。如果您将 longFunc 更改为在多个指令上发生的事情,例如繁忙循环,例如

    def longFunc():
        while True:
            pass
    

    然后它按预期工作。单次昂贵的计算是否适合您的情况,还是该示例恰好遇到了非常糟糕的情况?

    使用multiprocessing 模块似乎可以解决这个问题:

    from multiprocessing import Process
    
    def longFunc():
        # this expression could be entered by the user
        return 45 ** 10 ** 1000
    
    if __name__ == "__main__":
        thread = Process(target=longFunc, args=(), daemon=True)
        thread.start()
        thread.join(5.0)
        print("end")
    

    这会按预期打印"end"

    【讨论】:

    • 好吧,事情是用户将输入表达式,任何不好的表达式都应该被处理,如果不是,那么整个工作流程就会被阻塞,这是不希望的。 (表达式是在服务器端处理的,这显然很糟糕)
    • 如果您愿意使用多处理模块,那么这似乎可以解决问题(我已经用一个与您的原始示例相同的快速示例更新了我的答案)。如果我对与 GIL 交互的假设是正确的,我怀疑你不会找到使用默认 Python 线程的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 2016-04-26
    • 2017-09-13
    相关资源
    最近更新 更多