从另一个线程关闭挂起的zmq套接字

时间:2012-07-08 05:41:41

标签: python sockets zeromq pyzmq

有没有办法从Python中的另一个线程关闭特定的挂起recv zmq套接字而不破坏可能正在使用的其他套接字?以下代码似乎没有退出;用sock.close()替换ctx.destroy()导致它退出,但这显然会破坏上下文中的所有套接字:

import zmq
import time
import threading as th
ctx = zmq.Context()
sock = ctx.socket(zmq.ROUTER)
sock.bind('tcp://*:6000')
def shutdown():
    time.sleep(5)
    print 'closing'
    sock.close()
t = th.Thread(target=shutdown)
t.start()
try:
    sock.recv()
except zmq.ZMQError:
print 'closed'

1 个答案:

答案 0 :(得分:2)

一种可能性是在上下文管理器中执行套接字操作,该管理器使用在检测到信号时引发异常的信号处理程序来关闭套接字:

import zmq
import signal, time
import threading as th
from contextlib import contextmanager
@contextmanager
def ZMQErrorOnAlarm():
    def handler(signum, frame):
        raise Exception('ALARM detected')
    signal.signal(signal.SIGALRM, handler)
    yield
ctx = zmq.Context()
sock = ctx.socket(zmq.ROUTER)
sock.bind('tcp://*:6000')
def shutdown():
    signal.alarm(5)
    print 'closing'
t = th.Thread(target=shutdown)
t.start()
with ZMQErrorOnAlarm():
    try:
        sock.send('x')
        sock.recv()
    except:
        print 'closed'