2017-02-10 51 views
4

在我的一個應用程序中,我使用經銷商/路由器inproc連接。我將DEALER套接字上的逗留選項設置爲0,以便一旦ROUTER套接字關閉,在DEALER套接字上發送的所有消息都將被丟棄。雖然這對於TCP連接很有效,但它會阻止inproc。下面是一個最小的工作示例:如何幹淨地關閉zeromq經銷商/路由器inproc連接

#include <zmq.h> 

#include <windows.h> 

int main() 
{ 
    void *context = zmq_ctx_new(); 

    void *router = zmq_socket(context, ZMQ_ROUTER); 
    zmq_bind(router, "inproc://socket"); 

    void *dealer = zmq_socket(context, ZMQ_DEALER); 
    zmq_connect(dealer, "inproc://socket"); 

    int linger = 0; 
    zmq_setsockopt(dealer, ZMQ_LINGER, &linger, sizeof(linger)); 

    zmq_close(router); 

    // sleep for 1 ms 
    Sleep(1); 

    // this call blocks 
    zmq_send(dealer, "message", 7, 0); 

    zmq_close(dealer); 
    zmq_ctx_destroy(context); 

    return 0; 
} 

之前,經銷商插座可以關閉,zmq_send()調用塊。在這個最簡單的例子中,我不得不添加一個Sleep(1)調用。當這個調用被省略時,zmq_send()不會被阻塞。阻塞後,調用堆棧如下:

[External Code] 
libzmq.dll!zmq::signaler_t::wait(int timeout_) Line 253 C++ 
libzmq.dll!zmq::mailbox_t::recv(zmq::command_t * cmd_, int timeout_) Line 80 C++ 
libzmq.dll!zmq::socket_base_t::process_commands(int timeout_, bool throttle_) Line 1023 C++ 
libzmq.dll!zmq::socket_base_t::send(zmq::msg_t * msg_, int flags_) Line 869 C++ 
libzmq.dll!s_sendmsg(zmq::socket_base_t * s_, zmq_msg_t * msg_, int flags_) Line 346 C++ 
libzmq.dll!zmq_send(void * s_, const void * buf_, unsigned __int64 len_, int flags_) Line 371 C++ 

我使用Windows 10 64,libzmq 4.2.1(4.1.6與測試它),和Visual Studio 2015年我怎樣才能乾淨地關閉打開DEALER/ROUTER連接?這是libzmq中的錯誤嗎?

回答

1

難道是feasable使用ZMQ_DONTWAIT

zmq_send()

通話和評估錯誤代碼?

改變你的代碼

// this call blocks no more 
zmq_send(dealer, "message", 7, ZMQ_DONTWAIT); 
int ec = zmq_errno(); 
printf("code: %d\nstring: %s\n", ec, zmq_strerror(ec)); 

會導致

碼:11

字符串:資源暫時不可用

或者,可以在socket monitor來檢測關閉事件並防止進一步發送?這取決於你的架構。

相關問題