簡體   English   中英

通過SIGTERM間接停止python asyncio事件循環沒有任何效果

[英]Indirectly stopping a python asyncio event loop through SIGTERM has no effect

以下最小程序重現了該問題。

import asyncio
import signal

class A:
    def __init__(self):
        self._event_loop = asyncio.new_event_loop()

    def run(self):
        print('starting event loop')
        self._event_loop.run_forever()
        print('event loop has stopped')

    def stop(self):
        print('stopping event loop')
        self._event_loop.stop()


if __name__ == '__main__':
    a = A()

    def handle_term(*args):
        a.stop()

    signal.signal(signal.SIGTERM, handle_term)
    a.run()

如果運行程序並將SIGTERM發送到進程,則會調用第16行(停止事件循環)中的print語句,但程序不會終止,並且永遠不會調用第13行中的print語句(事件循環已停止)。 所以似乎事件循環永遠不會停止, self._event_loop.run_forever()無限期地阻塞。

為什么是這樣?

注意:程序的修改版本,其中a.stop()不是由信號處理程序調用,而是由具有延遲的單獨線程調用,按預期工作。 如何調用a.stop()什么不同?

而不是signal.signal()使用loop.add_signal_handler()

import asyncio
import signal

import os


class A:
    def __init__(self):
        self.loop = asyncio.new_event_loop()
        self.loop.add_signal_handler(signal.SIGTERM, self.stop)

    def stop(self):
        print('stopping')
        self.loop.stop()

    def run(self, close=True):
        print('starting loop')
        try:
            self.loop.run_forever()
            print('loop stopped')
        finally:
            if close:
                self.loop.close()


if __name__ == '__main__':
    print("to stop run:\nkill -TERM {}".format(os.getpid()))
    a = A()
    a.run()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM