2017-02-19 90 views
0

您可以看到完整的here如何取消使用`concurrent.futures.ProcessPoolExecutor`运行的长时间运行的子进程?

我的代码的简化版本如下:

executor = ProcessPoolExecutor(10) 
try: 
    coro = bot.loop.run_in_executor(executor, processUserInput, userInput) 
    result = await asyncio.wait_for(coro, timeout=10.0, loop=bot.loop) 
except asyncio.TimeoutError: 
    result="Operation took longer than 10 seconds. Aborted." 

不幸的是,当一个操作超时,该进程仍在运行,即使未来已经被取消。我如何取消该流程/任务以使其实际停止运行?

回答

1

ProcessPoolExecutor使用multiprocessing模块。没有取消的情况下,这不.terminate()子过程,建议使用multiprocessing.Event,让你的子进程正常退出:

import asyncio 
import multiprocessing 
import time 
from concurrent.futures.process import ProcessPoolExecutor 


def f(done): 
    print("hi") 

    while not done.is_set(): 
     time.sleep(1) 
     print(".") 

    print("bye") 

    return 12345 


async def main(): 
    done = manager.Event() 
    fut = loop.run_in_executor(None, f, done) 
    print("waiting...") 
    try: 
     result = await asyncio.wait_for(asyncio.shield(fut), timeout=3) 
    except asyncio.TimeoutError: 
     print("timeout, exiting") 
     done.set() 
     result = await fut 
    print("got", result) 

loop = asyncio.get_event_loop() 
loop.set_default_executor(ProcessPoolExecutor()) 
manager = multiprocessing.Manager() 

loop.run_until_complete(main())