如何使用asyncio清除和改进此python代码?
问题描述:
我正在编写一个python脚本来监视多个站点的状态。
因为它应该检查网站的状态在一个精确的时间间隔没有被其他网站阻止检查,我使用asyncio。
但是,当我捕捉到一个SIGINT信号时,它看起来并没有正确地停止,或者可能是我做错了一切。如何使用asyncio清除和改进此python代码?
/usr/lib/python3.5/asyncio/unix_events.py:129: RuntimeWarning: coroutine 'exit_sigint' was never awaited
del self._signal_handlers[sig]
exception calling callback for <Future at 0x7f146da3ee80 state=finished returned list>
Traceback (most recent call last):
File "/usr/lib/python3.5/concurrent/futures/_base.py", line 297, in _invoke_callbacks
callback(self)
File "/usr/lib/python3.5/asyncio/futures.py", line 442, in _call_set_state
dest_loop.call_soon_threadsafe(_set_state, destination, source)
File "/usr/lib/python3.5/asyncio/base_events.py", line 532, in call_soon_threadsafe
handle = self._call_soon(callback, args)
File "/usr/lib/python3.5/asyncio/base_events.py", line 506, in _call_soon
self._check_closed()
File "/usr/lib/python3.5/asyncio/base_events.py", line 334, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
的源代码:
https://github.com/DasFranck/Python-Mineur/blob/master/awsum_py/awsum.py
我应该怎么改变,那我做正确?
答
按照asyncio doc:
ensure_future
时间表协程对象的执行:在未来的包裹。返回一个Task对象。
你的回调运行,应该由你的循环管理协程,但你永远不run_until_complete
它,所以你永远等待它完成。事实上,通过像这样包装回调,你不能打电话给run_until_complete
。
无论如何,回调不必是异步,所以你可以使用它们像这样:
# exit_sigint doesn't even need the loop as a parameter
def exit_sigint(signame):
print("%s catched, exiting..." % signame)
for task in asyncio.Task.all_tasks():
task.cancel()
loop.add_signal_handler(getattr(signal, "SIGINT"), exit_sigint, "SIGINT")
loop.add_signal_handler(getattr(signal, "SIGTERM"), exit_sigint, "SIGTERM")
不用包裹他们入未来。