<p>找到一个将从异步函数调用self.\u loop.stop()</strong>的解决方案
这将首先等待所有其他任务。请注意,它不会等待自己!
如果它尝试,程序将锁定</p>
<p>此外,<strong>asyncio.wait_for(..)</strong>co例程允许超时</p>
<pre class="lang-py prettyprint-override"><code>import asyncio
import signal
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s [%(name)s]: %(message)s', datefmt='%H:%M:%S')
_log = logging.getLogger(__name__)
class Looper:
def __init__(self, loop):
self._loop = loop
self._shutdown = False
signal.signal(signal.SIGINT, self._exit)
signal.signal(signal.SIGTERM, self._exit)
async def _a_exit(self):
self._shutdown = True
my_task = asyncio.current_task()
pending = list(filter(lambda x: x is not my_task, asyncio.all_tasks(loop=self._loop)))
waiters = [asyncio.wait_for(p, timeout = 1.5, loop=self._loop) for p in pending]
results = await asyncio.gather(*waiters, loop=self._loop, return_exceptions=True)
n_failure = len(list(filter(lambda x: isinstance(x, Exception), results)))
_log.info(f"{n_failure} failed processes when quick-gathering the remaining {len(results)} tasks. Stopping loop now.")
self._loop.stop()
def _exit(self, sig, frame):
name = signal.Signals(sig).name
_log.info(f"Received shutdown-signal: {sig} ({name})")
self._loop.create_task(self._a_exit())
async def thumper(self, id, t):
print(f"{id}: Winding up...")
while not self._shutdown:
await asyncio.sleep(t)
print(f'{id}: Thump!')
print(f'{id}: Thud.')
loop = asyncio.get_event_loop()
lp = Looper(loop)
loop.create_task(lp.thumper('North Hall', 1))
loop.create_task(lp.thumper('South Hall', 2))
loop.create_task(lp.thumper(' West Hall', 3))
loop.create_task(lp.thumper(' East Hall', 4))
loop.run_forever()
_log.info("Done.")
</code></pre>
<p>在Windows 10上,这可能导致输出</p>
<pre><code>North Hall: Winding up...
South Hall: Winding up...
West Hall: Winding up...
East Hall: Winding up...
North Hall: Thump!
South Hall: Thump!
[..]
South Hall: Thump!
North Hall: Thump!
14:20:59 INFO [__main__]: Received shutdown-signal: 2 (SIGINT)
West Hall: Thump!
West Hall: Thud.
North Hall: Thump!
North Hall: Thud.
South Hall: Thump!
South Hall: Thud.
14:21:01 INFO [__main__]: 1 failed processes when quick-gathering the remaining 4 tasks. Stopping loop now.
14:21:01 INFO [__main__]: Done.
</code></pre>
<p>失败的进程受到超时的影响</p>
<p>请注意,这解决了我的问题。但是,调用<strong>loop.stop()</strong>后,为什么<strong>loop.run\u直到\u complete(..)</strong>失败的问题仍然存在</p>