[英]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.