簡體   English   中英

停止包含阻塞循環的python線程

[英]Stop python thread that contains blocking loop

我正在嘗試設計與ZeroMQ的面向對象的接口。

我不想在進程中使用zmq接收器,但我不希望它使用其循環來阻塞進程。 所以我試圖在另一個線程中開始循環。

class BaseZmqReceiver(BaseZmqNode):
    __metaclass__ = ABCMeta

    def __init__(self, host, port, hwm, bind, on_receive_callback):
        super(BaseZmqReceiver, self).__init__(host=host, port=port, bind=bind, hwm=hwm)
        self.node.on_message_callback = on_receive_callback
        self.stream = ZMQStream(self.socket)
        self.stream.on_recv(self.on_message_received)
        ZmqLoopRunner().start()

    def on_message_received(self, message):
        return self.node.on_message_callback(message)

    def create_node(self):
        return ReceivingNode(None, None)

class ZmqLoopRunner(Thread):

    def __init__(self):
        super(ZmqLoopRunner, self).__init__()
        self.loop = IOLoop.instance()

    def run(self):
        self.loop.start()

    def stop(self):
        self.loop.stop()

但是我不知道如何正確停止該線程,因為loop.start()方法正在阻塞。 我怎樣才能做到這一點?

1)如果是關於Tornado IOLoop( 更新:不是 ),正確的方法是在單個IOLoop中使用無阻塞集成

2)要手動停止IOLoop,可以從IOLoop線程調用IOLoop.instance().stop()

IOLoop.instance().add_callback(IOLoop.instance().stop)

add_callback()確保在IOLoop事件線程內調用stop()方法,並且IOLoop干凈地停止。

在您的代碼中,這將是:

class BaseZmqReceiver(BaseZmqNode):
    __metaclass__ = ABCMeta

    def __init__(self, host, port, hwm, bind, on_receive_callback):
        super(BaseZmqReceiver, self).__init__(
            host=host, port=port, bind=bind, hwm=hwm)
        # ...
        self.zmq_runner = ZmqLoopRunner()
        # this will start a new thread.
        self.zmq_runner.start()

    def stop(self):
        self.zmq_runner.stop()

class ZmqLoopRunner(Thread):
    # ...
    def stop(self):
        """ 
        Call this from any thread, add_callback() will make sure 
        it runs in IOLoop thread.
        """
        self.loop.add_callback(self.loop.stop)  # Note the absence of parentheses

3)如果需要線程在程序關閉時退出,則可以將其設置為daemon 更糟糕的是,它無法徹底關閉IOLoop

class ZmqLoopRunner(Thread):
    def __init__(self):
        super(ZmqLoopRunner, self).__init__()
        self.daemon = True

暫無
暫無

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

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