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