5

我有两个问题concurrent.futures从concurrent.futures到ASYNCIO

如何突破time.sleep()在Python concurrent.futures?

结论:time.sleep()不能被打断。一个解决方案是:你可以在它周围写一个循环,并做短暂的睡眠。

How to break time.sleep() in a python concurrent.futures

个人超时的concurrent.futures?

结论:个别超时需要由用户执行。例如:对于每个超时,您可以拨打wait()

Individual timeouts for concurrent.futures

问题

是否asyncio解决问题的论文?

+0

为了自我控制,你能在这里总结其他两个问题吗? – deceze

+0

@deceze,我更新了问题并添加了我的结论。这是好的,还是缺少一些东西? – guettli

+0

现在看起来更多,谢谢。 – deceze

回答

5

在asyncio模型中,执行是由事件循环调度和协调的。要取消执行当前挂起的任务,你基本上只需要就不会恢复它。虽然这在实践中有点不同,但显而易见的是,这使得在理论上取消暂停的任务变得简单。单独的超时当然可能是相同的:每当你暂停一个协程来等待一个结果时,你想提供一个超时值。事件循环将确保在达到超时并且任务尚未完成时取消正在等待的任务。

一些具体的示例:

class Foo: 
    task = None 

    async def sleeper(self): 
     self.task = asyncio.sleep(60) 
     try: 
      await self.task 
     except concurrent.futures.CancelledError: 
      raise NotImplementedError 

虽然这种方法是睡着了,别人可以拨打foo.task.cancel()唤醒协程:

>>> import asyncio 
>>> loop = asyncio.get_event_loop() 
>>> task = asyncio.ensure_future(asyncio.sleep(5)) 
>>> task.cancel() 
>>> loop.run_until_complete(task) 
Traceback (most recent call last): 
    ... 
concurrent.futures._base.CancelledError 

在实践中,这可能会使用这样的事情来实现并让它处理取消。或者,拨打sleeper()的人可以直接取消,但不给它一个清理机会。

设置超时也同样简单:

>>> loop.run_until_complete(asyncio.wait_for(asyncio.sleep(60), 5)) 
[ ... 5 seconds later ... ] 
Traceback (most recent call last): 
    ... 
concurrent.futures._base.TimeoutError 

特别是在HTTP请求超时的情况下,看到aiohttp

async def fetch_page(session, url): 
    with aiohttp.Timeout(10): 
     async with session.get(url) as response: 
      assert response.status == 200 
      return await response.read() 

with aiohttp.ClientSession(loop=loop) as session: 
    content = loop.run_until_complete(fetch_page(session, 'http://python.org')) 

显然每次调用fetch_page可以自行aiohttp.Timeout价值决定,并当达到超时时,每个单独的实例将抛出它自己的异常。

+0

哇,很好的答案。谢谢。想象一下,我使用子进程模块(我读它支持),然后我想以某种方式终止子进程。你有一个提示如何做到这一点? – guettli

+0

不是,不。你应该为此提出一个新问题。 – deceze

+2

@guettli查看[asyncio.subprocess](https://docs.python.org/3/library/asyncio-subprocess.html)模块和那些[示例](http://asyncio.readthedocs.io /en/latest/subprocess.html)。 – Vincent