2017-02-19 115 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())