0MQ是会阻塞的,不要字面上看到队列就等同非阻塞。

如果你是希望通过0MQ来做缓冲队列,非阻塞的效果,那你就必须清楚 0MQ Socket是会阻塞,你要搞清楚0MQ Socket与队列的关系。

官方协议文档规定了,一部分类型的 0MQ Socket为不阻塞发送,而另一部分类型则是阻塞发送的。不阻塞发送同时往往也意味着丢弃消息,相反不能丢弃消息的则要求阻塞发送。这里的阻塞发送,不是说像tcp那样确保送到目的地,而是必须有目的地可以发送。而队列的作用就是架在发送端和目的地之间作缓冲。如果连目的地也没有,那么队列也就失去存在的意义了,所以只好将发送阻塞起来。到这里你可能会撇嘴,不是发送端缓冲在队列,在接收端建立起连接后,接收端从队列中取消息。这是你相像出来的 0MQ,而非人家设计出来 0MQ。还是要看人家的(协议设计)文档。

各种类型的详细行为责任定义:

The PAIR Socket Type

  • SHALL create a double queue when initiating an outgoing connection to a peer, and SHALL maintain the double queue whether or not the connection is established.
  • SHALL create a double queue when a peer connects to it. If this peer disconnects, the PAIR socket SHALL destroy its double queue and SHALL discard any messages it contains.

The PULL Socket Type

  • SHALL create this queue when initiating an outgoing connection to a peer, and SHALL maintain the queue whether or not the connection is established.
  • SHALL create this queue when a peer connects to it. If this peer disconnects, the PULL socket SHALL destroy its queue and SHALL discard any messages it contains.

The PUSH Socket Type

  • SHALL create this queue when initiating an outgoing connection to a peer, and SHALL maintain the queue whether or not the connection is established.
  • 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.

从上面一般行为规定可以看到,队列是与底层socket连接对应的,当底层没有任何socket连接时,队列就不存在。所以发送行为就有下面这样的规定。

The PAIR Socket Type

  • SHALL consider its peer as available only when it has a outgoing queue that is not full.
  • SHALL block on sending, or return a suitable error, when it has no available peer.
  • SHALL not accept further messages when it has no available peer.
  • SHALL NOT discard messages that it cannot queue.

The PUSH Socket Type

  • SHALL consider a peer as available only when it has a outgoing queue that is not full.
  • SHALL route outgoing messages to available peers using a round-robin strategy.
  • SHALL block on sending, or return a suitable error, when it has no available peers.
  • SHALL not accept further messages when it has no available peers.
  • SHALL NOT discard messages that it cannot queue.

The DEALER Socket Type

  • SHALL consider a peer as available only when it has a outgoing queue that is not full.
  • SHALL route outgoing messages to available peers using a round-robin strategy.
  • SHALL block on sending, or return a suitable error, when it has no available peers.
  • SHALL not accept further messages when it has no available peers.
  • SHALL NOT discard messages that it cannot queue.

The REQ Socket Type

  • SHALL prefix the outgoing message with an empty delimiter frame.
  • SHALL route outgoing messages to connected peers using a round-robin strategy.
  • SHALL block on sending, or return a suitable error, when it has no connected peers.
  • SHALL NOT discard messages that it cannot send to a connected peer.

 

1. 红色字眼 block on,说明了 0MQ Socket 在发送过程有可以阻塞。

2. ”consider a peer as available only when it has a outgoing queue that is not full“, 特别要注意peer,首先要有连接,只要这个连接关联的发送队列不满也就可以视作可以发送。

3. "block on sending, or return a suitable error, when it has no connected/available peers", 当没有可以发送的peer,(意思是a. 有连接但发送队列满;b. 无任何连接,也就没有队列了。)要么阻塞发送,要么就返回错误给调用者,由调用者自己决定丢弃消息或其它方式处理。

4. "not accept further messages when it has no available peers",这里是指 0MQ Socket 层不接受 0MQ Socket使用者发送的消息,不是说底层连接不接收消息。

 

现在是否清楚使用 0MQ时,在什么情况下可能会被阻塞了。

posted on 2017-10-30 14:39  bbqz007  阅读(1628)  评论(0编辑  收藏  举报