2011-10-29 11 views
2

pyzmqで存在しないソケットに接続すると、プログラムを停止するためにCTRL_Cを押す必要があります。誰かがなぜこのことが起きるのだろうか?多くの場合無効なソケットに接続するとPythonでZeromqがハングする

import zmq 

INVALID_ADDR = 'ipc:///tmp/idontexist.socket' 

context = zmq.Context() 
socket = context.socket(zmq.REQ) 

socket.connect(INVALID_ADDR) 
socket.send('hello') 

poller = zmq.Poller() 
poller.register(socket, zmq.POLLIN) 
conn = dict(poller.poll(1000)) 
if conn: 
    if conn.get(socket) == zmq.POLLIN: 
     print "got result: ", socket.recv(zmq.NOBLOCK) 
else: 
    print 'got no result' 

答えて

8

この質問はGitHubのpyzmq Issueでもありました。私はここで私の説明を言い換えます(私はそれが適切であることを望みます、私はかなり新しいです):

一般的なルール:疑問があるときは、LERERによるzeromqプログラムの最後にハングアップします。

ここでのハングは、LINGERソケットオプションによって発生し、スクリプトの最後にガベージコレクション中に呼び出されるcontext.term()メソッドで発生します。 LERERの動作はzeromq docsのdescribedですが、単純に言えば、メッセージを削除する前にソケットを閉じた後にキュー内のメッセージが処理されるのを待つのはタイムアウト(ミリ秒単位)です。デフォルトの動作はLINGER=-1です。これは永遠に待機することを意味します。

この場合、ピアが開始されていないので、送信しようとした 'hello'メッセージは、ソケットが閉じようとしたときに送信キューで待機しています。 LINGER=-1を指定すると、ZeroMQはピアがシャットダウンする前にそのメッセージを受信する準備ができるまで待機します。このスクリプトが明らかにハングしている間にREPソケットを 'ipc:///tmp/idontexist.socket'にバインドすると、メッセージが配信され、スクリプトはきれいに終了します。

あなたのスクリプトを待たせたくない場合(返信時にすでに断っておいた印刷文のように)、LINGERを負でない値(例えばsocket.linger = 0)に設定し、context.term()は指定されたミリ秒数を待機します。

INVALID_ADDR変数名は、まだリスナーを持たないインターフェイスへの接続が無効であることを示しています。これは間違っています。 zeromqは、送信スクリプトがterm()でブロックされている間に、REPソケットをインターフェイスにバインドするという、上記の動作によって示されるように、バインド/接続イベントが任意の順序で発生することを許可します。

+1

ありがとう、LINGERオプションは、私のアプリが終了時にぶら下がるのを止めるために必要なものでした! – aknuds1

0

、あなたはそう、あなたの接続、いずれかの順序でZMQソケットをバインドし、接続することができます()/(送信)単にので、来たことがない他の終了時)(対応するバインドを待っていますプログラムがハングアップするようです。いくつかのロギングステートメントを印刷して、プログラムがハングしている場所を確認してください。

関連する問題