多处理线程池未按预期终止

时间:2016-04-15 15:22:42

标签: python multiprocessing

我在Windows 7上运行Python 3.4。

我正在尝试更多地了解多处理,并尝试编写一个在另一个函数调用上执行干净的小超时的函数。但我遇到了一个我无法弄清楚的问题。

根据关于多处理的Python文档:

  

Terminate()“立即停止工作进程而不完成未完成的工作。”

然而,当我测试它时,pool.terminate()似乎等待工作进程完成而不是杀死它们!

所以当我运行这段代码时:

import multiprocessing.pool
from time import sleep

def timeout(seconds, function, *args, **kwargs):

    pool = multiprocessing.pool.ThreadPool(processes = 1)
    result = pool.apply_async(function, args, kwargs)

    try: result.get(seconds)
    except multiprocessing.context.TimeoutError:
        print("Process timed out")
        pool.terminate()
        pool.join()
        print("Pool terminated")
    finally:
        pool.close()

def worker():
    for n in range(5):
        sleep(1)
        print(n+1)
    print("Process succeeded")

timeout(2.5, worker)

我希望结果如下:

1
2
Process timed out
Pool terminated

但我得到了这个:

1
2
Process timed out
3
4
5
Process succeeded
Pool terminated

我知道result.get提出TimeoutError因为“处理超时”消息已成功打印。而且我知道pool.terminate()因为同样的原因被召唤,它似乎什么都没做!

我觉得这里有些东西我只是不理解。有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:2)

我不知道为什么,但这个问题似乎是由terminate()调用引起的,你实际上并不需要这个调用,因为工作进程可能被前面的import multiprocessing.pool from time import sleep def timeout(seconds, function, *args, **kwargs): pool = multiprocessing.pool.ThreadPool(processes=1) result = pool.apply_async(function, args, kwargs) try: result.get(timeout=seconds) except multiprocessing.TimeoutError: print("Process timed out") pool.terminate() # pool.join() # Don't need this, all worker threads have been stopped. print("Pool terminated") def worker(): for n in range(5): sleep(1) print(n+1) print("Process succeeded") timeout(2.5, worker) 终止了调用

1
2
Process timed out
Pool terminated

输出:

Pool

无论如何,请注意,自版本3.3以来,Pool.terminate()对象支持上下文管理协议,这意味着def timeout(seconds, function, *args, **kwargs): with multiprocessing.pool.ThreadPool(processes=1) as pool: result = pool.apply_async(function, args, kwargs) try: result.get(timeout=seconds) except multiprocessing.TimeoutError: print("Process timed out") print("Pool terminated") 将在使用时自动调用 - 因此函数可以更简洁地编写如下:

{{1}}
相关问题