【问题标题】:zmq_ctx_term() blocks while sockets closed套接字关闭时 zmq_ctx_term() 阻塞
【发布时间】:2015-07-30 07:11:07
【问题描述】:

我正在使用 ZMQ,但在销毁上下文时遇到了问题。

我有密码

zmq_ctx_shutdown(context);
zmq_ctx_term(context);

这段代码总是阻塞在zmq_ctx_term(),也会阻塞zmq_ctx_destoy();但是,如果该调用被删除并且只使用了 shutdown 调用,一切似乎都可以正常工作,但应用程序会因为不释放 zmq 上下文而泄漏内存。

在我的代码中,我有四个套接字:两个 ZMQ_PAIR inproc 套接字,用于在主线程和带有 ZMQ_REP 套接字的线程之间进行通信,以及在主线程上运行的 ZMQ_PUB线程。

我已将所有这些套接字上的 ZMQ_LINGER 设置为 0,因为似乎唯一一次应该阻止 zmq_ctx_term() 调用是因为我在所有套接字上调用了 zmq_close() 之后尚未发送消息,这返回没有错误。此外,如果我只调用zmq_ctx_new(),创建套接字,然后调用zmq_ctx_shutdown(); zmq_ctx_term();,这种阻塞仍然会发生。

我担心使用两个 inproc 套接字在具有相同 zmq 上下文的线程之间进行通信会出现问题,尽管在接收消息时通信似乎没有任何问题。

在担心我可能会遇到线程安全问题后,我发现 ZMQ 上下文应该是线程安全的,而不是套接字。我已经检查并在主线程中打开了一个关闭ZMQ_PUB 套接字和inproc 套接字。在另一个线程中,我正在打开和关闭ZMQ_REP 套接字和inproc 套接字的另一端,所以这似乎不是问题。

为澄清起见,我正在使用 GitHub 上当前 master 分支的 libzmq 用 C 语言编写代码(提交 d35473e)。在链接 ZMQ 的共享库时,我确实看到了类似的问题,尽管无论我使用静态库还是共享库都会发生这种情况。我目前使用的是 OS X 10.9。

如果有人有时间看整个代码,相关文件列here

知道这里发生了什么吗?

【问题讨论】:

  • 虽然文档说(zmq_ctx_shutdown)“此函数是可选的,但仍需要客户端代码调用 zmq_ctx_term 函数以释放 ZeroMQ 分配的所有资源。”,我正在运行也陷入困境。我现在是not doingzmq_ctx_term,如果我这样做了zmq_ctx_shutdown
  • @metadings 除了没有调用zmq_ctx_term 的内存泄漏之外,我没有遇到任何问题,事实上,在我阅读zmq_ctx_shutdown 的文档之前,我认为我在做正确的事情。看起来您不应该在 Shutdown 调用中将上下文设置为空指针,因为它仍然需要终止。
  • zmq_ctx_term() 上阻塞时堆栈跟踪是什么样的?
  • @Xaqq 无论哪种情况,我都能看到的最后一个调用是poll()epoll() 调用,我认为它们来自阻塞套接字,尽管我必须发送@987654351 @ 停止执行,所以我不确定这是否会影响任何事情。目前,即使我在调试模式下构建,zmq 调试符号也没有显示给我,所以我试图弄清楚还有什么情况。

标签: c multithreading sockets zeromq


【解决方案1】:

观察:

我遇到了同样的问题。尽管我关闭了ZMQ_REQ 类型的套接字,并且zmq_close() 返回了0zmq_ctx_term() 仍然会阻塞。只有在向未运行的对等方发送消息后才会发生这种情况。

zmq_send() 会立即返回,但zmq_recvmsg() 会超时。

之后我关闭了套接字并调用了zmq_ctx_term()。显然,尽管zmq_close() 返回了0,但发送的消息仍在传出队列中,因此zmq_ctx_term() 会阻塞。

解决方案:

我通过将 ZMQ_LINGER 选项设置为 ZMQ_RCVTIMEO 值的一半解决了这个问题。这里实际上描述了这种行为 http://api.zeromq.org/4-0:zmq-ctx-term

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    相关资源
    最近更新 更多