在python中使用线程的超时功能不起作用

在python中使用线程的超时功能不起作用,第1张

在python中使用线程的超时功能不起作用

一个线程不能优雅地杀死另一个线程,因此对于您当前的代码,它

foo
永远不会终止。(使用
thread.daemon =True
Python程序时,仅保留守护程序线程将退出,但这不允许您在
foo
不终止主线程的情况下终止。)

有些人]试图使用信号来停止执行,但这在某些情况下可能不安全。

如果可以修改

foo
,则有许多解决方案。例如,您可以检查是否
threading.Event
要退出while循环。

但是,如果您不能修改

foo
,则可以使用该
multiprocessing
模块在子进程中运行它,因为与线程不同,子进程可以终止。这是看起来的示例:

import timeimport multiprocessing as mpdef foo(x = 1):    cnt = 1    while True:        time.sleep(1)        print(x, cnt)        cnt += 1def timeout(func, args = (), kwds = {}, timeout = 1, default = None):    pool = mp.Pool(processes = 1)    result = pool.apply_async(func, args = args, kwds = kwds)    try:        val = result.get(timeout = timeout)    except mp.TimeoutError:        pool.terminate()        return default    else:        pool.close()        pool.join()        return valif __name__ == '__main__':    print(timeout(foo, kwds = {'x': 'Hi'}, timeout = 3, default = 'Bye'))    print(timeout(foo, args = (2,), timeout = 2, default = 'Sayonara'))

产量

('Hi', 1)('Hi', 2)('Hi', 3)Bye(2, 1)(2, 2)Sayonara

请注意,这也有一些限制。

  • 子流程接收父流程变量副本 。如果您在子流程中修改变量,则 不会 影响父流程。如果您的函数

    func
    需要修改变量,则需要使用共享变量。

  • 参数(通过传递

    args
    )和关键字(
    kwds
    )必须是可腌制的。

  • 进程比线程更多的资源。通常,您只想在程序开始时创建一次多处理池。每次调用时都会

    timeout
    创建此函数
    Pool
    。这是必要的,因为我们需要
    pool.terminate()
    终止
    foo
    。也许有更好的方法,但是我还没有想到。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5644396.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存