问题
I'm trying to use the ZeroMQ Poller()
functionality with two sockets in 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")
And then the server that sends messages as a ROUTER
is described as:
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()
But when I run these two processes, it does not work as expected, the poller-script does not print anything. What could be the problem of such implementation?
回答1:
Q : "What could be the problem of such implementation?"
such implementation is prone to deadlock & fails due to using exclusively the blocking-forms of
.poll()
&.recv()
methodssuch implementation is not self-defending enough in cases, where multiple peers get connected into AccessPoints, that implement round-robin incoming/outgoing traffic mappings
such implementation is awfully wrong in standing self-blinded in calling just a single
.recv()
in cases, where the.send_multipart()
is strikingly warning, there will be multi-part message-handling neededipc://
Transport Class is prone to hide O/S related user-level code restrictions ( placed by the operating system on the format and length of a pathname and effective user-rights to R/W/X there )ipc://
Transport Class.connect()
-method's use is order-dependent for cases the target-address has not yet been created by O/S services ( a successful.bind()
needs to happen first )last but not least, any next attempt to
.bind()
onto the sameipc://
Transport Class target will silently destroy your intendedROUTER
-access to the messaging/signalling-plane infrastructure & your implementation has spent zero-efforts to self-protect and self-diagnose errors that might silently appear "behind the curtains"
Shouldn't zeromq deal automatically with deadlocks? I tried using the example given in the zeromq guide mspoller If I can't use .poll() and recv() simultaneously, how should I use ZMQ Poller structure? – hao123
No,
ZeroMQ zen-of-zero is performance + low-latency focused, so kindly consider all due care for blocking-prevention to be in your own hands (as needed & where needed, the core lib will never do a single more step than needed for the goal of achieving an almost linear scalable performance ).
No,
use freely both .poll()
- & .recv()
-methods, yet complete it so as to fit into a non-blocking fashion - .poll( 0 )
& add active detection + handling of multi-part messages ( again, best in a non-blocking fashion, using zmq.NOBLOCK
option flag where appropriate ). Self-blocking gets code out of control.
来源:https://stackoverflow.com/questions/64608767/why-is-zeromq-poller-not-receiving-messages-python