问题
This code will raise Resource temporarily unavailable when call with NOBLOCK:
context = zmq.Context()
sender = context.socket(zmq.PUSH)
sender.bind('tcp://*:15556')
sender.send('KeEpAliv', zmq.NOBLOCK) # this line will throw exception
#sender.send('KeEpAliv') # this line will ok
After read the docs, I found no hints for this. but docs for recv explained this flag.
回答1:
Python wrappers raise zmq.error.Again
if the underlying C API returns EAGAIN
.
Now, you should follow to zmq_send documentation, which states:
ZMQ_NOBLOCK
Specifies that the operation should be performed in non-blocking mode. If the message cannot be queued on the socket, the zmq_send() function shall fail with errno set to EAGAIN.
Also, in the errors section:
EAGAIN
Non-blocking mode was requested and the message cannot be sent at the moment.
Now, why is it not possible to send any message? On the page describing PUSH/PULL sockets we can read the following about the PUSH
socket:
SHALL create this queue when a peer connects to it. If this peer disconnects, the PUSH socket SHALL destroy its queue and SHALL discard any messages it contains.
Before any peer connects to your socket, there's nowhere to send the messages, and there's no queue. Thus only 2 things are possible:
- if you call
send()
in blocking mode, it blocks until a peer connects - if you call
send()
in non-blocking mode, it raiseszmq.error.Again
to inform you, that there's nothing that could be done with the message and you should try again later.
Note, that you can also get this exception if queues for each of the connected peers are full (PUSH
socket creates a separate queue for each connected peer).
来源:https://stackoverflow.com/questions/21826357/zmq-send-with-noblock-raise-resource-temporarily-unavailable