4

私のアプリケーションの 1 つで、DEALER/ROUTER インプロセス接続を使用しています。DEALER ソケットの linger オプションを 0 に設定して、ROUTER ソケットが閉じられると DEALER ソケットで送信されたすべてのメッセージが破棄されるようにします。これは TCP 接続ではうまく機能しますが、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;
}

DEALER ソケットを閉じる前に、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 x64、libzmq 4.2.1 (4.1.6 でもテスト済み)、および Visual Studio 2015 を使用しています。DEALER/ROUTER 接続を完全にシャットダウンするにはどうすればよいですか? これは libzmq のバグですか?

4

1 に答える 1