问题描述
我正在尝试将ZeroMQ Poller()
功能与python中的两个套接字一起使用:
import zmq
# Prepare our context and sockets
context = zmq.Context()
receiver = context.socket(zmq.DEALER)
receiver.connect("ipc:///tmp/interface-transducer")
subscriber = context.socket(zmq.SUB)
subscriber.bind("ipc:///tmp/fast-service")
subscriber.setsockopt(zmq.SUBSCRIBE,b"10001")
# Initialize poll set
poller = zmq.Poller()
poller.register(receiver,zmq.POLLIN)
poller.register(subscriber,zmq.POLLIN)
# Process messages from both sockets
while True:
try:
socks = dict(poller.poll())
except KeyboardInterrupt:
break
if receiver in socks:
message = receiver.recv()
print("RECEIVER OK\n")
if subscriber in socks:
message = subscriber.recv()
print("SUBSCRIBER OK\n")
然后将以ROUTER
形式发送消息的服务器描述为:
def main():
context = zmq.Context()
router = context.socket(zmq.ROUTER)
router.bind("ipc:///tmp/interface-transducer")
while True:
identity = b'electrode-service'
b_identity = identity
router.send_multipart([b_identity,b'[1,2]'])
print("Sent")
time.sleep(1)
if __name__ == "__main__":
main()
但是当我运行这两个进程时,它无法按预期运行,轮询器脚本不会打印任何内容。这样实施可能是什么问题?
解决方法
Q :“这种实施方式可能是什么问题?”
-
这样的实现容易死锁,并且由于专门使用
.poll()
和.recv()
方法的阻塞形式而失败 -
在多个对等点连接到AccessPoints并实现循环传入/传出流量映射的情况下,这种实现方式的自我防御能力不足
-
在
.recv()
发出警告的情况下,这种实现方式完全错误,只能调用单个.send_multipart()
,这是非常错误的,需要进行多部分消息处理 -
ipc://
传输类易于隐藏与操作系统相关的用户级别代码限制(由操作系统根据路径名的格式和长度以及对R / W / X在那里 -
ipc://
传输类.connect()
-的使用取决于顺序,以用于O / S服务尚未创建目标地址的情况(成功的.bind()
需要首先发生) -
最后但并非最不重要的一点是,下次尝试
.bind()
到相同的ipc://
传输类目标时,都会无声地破坏您想要的ROUTER
-对消息传递/信令平面的访问基础架构和您的实现花费了零的努力来自我保护和自我诊断错误,这些错误可能会悄无声息地出现在“幕后”
zeromq不会自动处理死锁吗?我尝试使用zeromq指南mspoller中给出的示例。如果不能同时使用.poll()和recv(),应该如何使用ZMQ Poller结构? – hao123
否,
ZeroMQ zen-of-zero注重性能+低延迟,因此,请妥善考虑所有对阻止阻塞的注意事项(根据需要在需要的地方,核心库绝不会比实现几乎线性的可扩展性能的目标多做任何一步。
否,
自由使用.poll()
-和.recv()
-方法,但都可以完成以适应非阻塞方式- .poll( 0 )
,并添加主动检测+处理多部分邮件(同样,最好以非阻塞的方式使用zmq.NOBLOCK
选项标志)。自阻止使代码失去控制。