web-dev-qa-db-ja.com

zmqポーラーはどのように機能しますか?

私はポーラーがzmqで実際に行うことに関して混乱しています。 zguideは最小限の説明であり、複数のソケットから読み取る方法としてのみ説明しています。これは、タイムアウトソケットの使用方法を説明していないため、満足のいく答えではありません。私は知っている zeromq:無限待機を防ぐ方法? Push/Pullについては説明していますが、req/repパターンについては説明していません。

私が尋ねようとしているのは、ポーラーはどのように機能し、その機能はソケットとそのリクエストの追跡にどのように適用されるのかということです。

42
user1876508

同じスレッド内の異なるソケットでリッスンする必要がある場合は、ポーラーを使用します。

_ZMQ.Socket subscriber = ctx.socket(ZMQ.SUB)
ZMQ.Socket puller = ctx.socket(ZMQ.PULL)
_

ポーラーでソケットを登録します(POLLINは着信メッセージをリッスンします)

_ZMQ.Poller poller = ZMQ.Poller(2)
poller.register(subscriber, ZMQ.Poller.POLLIN)
poller.register(puller, ZMQ.Poller.POLLIN)
_

ポーリングするときは、ループを使用します。

_while( notInterrupted()){
  poller.poll()

  //subscriber registered at index '0'
  if( poller.pollin(0)) 
     subscriber.recv(ZMQ.DONTWAIT)

  //puller registered at index '1'
  if( poller.pollin(1))
     puller.recv( ZMQ.DONTWAIT)
}
_

投票方法を選択してください...

poller.poll()は、いずれかのソケットにデータがあるまでブロックします。
poller.poll(1000)は1秒間ブロックしてからタイムアウトします。

ポーラーは、ソケットで使用可能なデータ(メッセージ)がある場合に通知します。それを読むのはあなたの仕事です。

読むときは、ブロックせずに実行してください:socket.recv( ZMQ.DONTWAIT)poller.pollin(0)は、読み込むデータがあるかどうかをチェックしますが、ポーリングループ内での呼び出しをブロックしないようにする必要があります。そうしないと、「スタック」ソケットによりポーラーがブロックされる可能性があります。

したがって、2つの別々のメッセージがsubscriberに送信される場合、ポーラーをクリアするためにsubscriber.recv()を2回呼び出す必要があります。そうでない場合は、subscriber.recv()を1回呼び出すと、ポーラーは、読むべき別のメッセージがあることを通知し続けます。そのため、本質的に、ポーラーは実際のメッセージではなく、メッセージの可用性と数を追跡します。

ポーリングの例に目を通し、コードを試してみてください。これが最良の学習方法です。

それはあなたの質問に答えますか?

58
raffian