我有一个在事件循环中永远运行的监视器,我想在接收sigint信号时正确关闭它( Ctrl + C )。 请考虑以下示例
class Scheduler(object):
def __init__(self, tasks=None, interval=1):
self.tasks = tasks or []
self.interval = interval
async def run_forever(self):
while True:
await self.run_once()
print('Waiting %s seconds to make next update...' %
self.interval)
await asyncio.sleep(self.interval)
async def run_once(self):
await asyncio.gather(*self.tasks)
async def cleanup(self):
print('Cleaning up resources...')
async def run(scheduler):
try:
await scheduler.run_forever()
finally:
await scheduler.cleanup()
def main():
loop = asyncio.get_event_loop()
scheduler = Scheduler()
loop.run_until_complete(run(scheduler))
if __name__ == '__main__':
main()
但它并没有在finally子句
中调用清理函数DEBUG:asyncio:Using selector: EpollSelector
Waiting 1 seconds to make next update...
Waiting 1 seconds to make next update...
^CTraceback (most recent call last):
File "shce.py", line 60, in <module>
main()
File "shce.py", line 50, in main
loop.run_until_complete(run(scheduler))
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 454, in run_until_complete
self.run_forever()
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 421, in run_forever
self._run_once()
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 1395, in _run_once
event_list = self._selector.select(timeout)
File "/usr/local/lib/python3.6/selectors.py", line 445, in select
fd_event_list = self._epoll.poll(timeout, max_ev)
KeyboardInterrupt
但下面的代码可以正常使用
def main():
loop = asyncio.get_event_loop()
scheduler = Scheduler()
try:
loop.run_until_complete(scheduler.run_forever())
except KeyboardInerrupt:
print('Soo god')
finally:
loop.run_until_complete(scheduler.cleanup())
第一个代码示例中缺少什么,它不想调用清理代码,它与第二个代码示例有什么不同?
答案 0 :(得分:1)
两个片段都是平等的,并且做同样的工作。
从我的角度来看,第二个看起来更优雅。