一个线程不能优雅地杀死另一个线程,因此对于您当前的代码,它
foo永远不会终止。(使用
thread.daemon =TruePython程序时,仅保留守护程序线程将退出,但这不允许您在
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
。也许有更好的方法,但是我还没有想到。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)