2011-10-29 50 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

這個問題也是posted作爲pyzmq在GitHub上的問題。我將在這裏解釋我的解釋(我希望這是適當的,我對SO相當新穎):

一般規則:如果有疑問,掛起到零點程序的結尾是由於LINGER造成的。

這裏的掛起是由LINGER套接字選項引起的,發生在腳本最後的垃圾回收期間調用的context.term()方法中。在zeromq文檔中,LINGER的行爲是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插座,所以你的連接()/發送()僅僅是等待相應的bind()的另一端,它永遠不會到來,所以該程序似乎掛起。檢查程序掛在哪裏打印出一些日誌報表...