我正在使用ZMQ(zmq.hpp)编写MFC应用程序的扩展。当我试图从应用程序卸载我的DLL时,zmq_ctx_destroy()函数将永远挂起。
我找到a similar issue,但没有答案。
我试图调试它并发现它在第一行的函数zmq :: thread_t :: stop()中停止:
DWORD rc = WaitForSingleObject (descriptor, INFINITE);
它甚至没有发送任何东西。简化代码如下所示:
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REQ);
socket.connect(ENDPOINT.c_str());
离开范围时,套接字和上下文被破坏。
调用堆栈:
libzmq-v100-mt-gd-4_0_4.dll! zmq::thread_t::stop() Line 56 + 0x17 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::select_t::~select_t() Line 57 + 0x13 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::select_t::`scalar deleting destructor'() + 0x2c bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::io_thread_t::~io_thread_t() Line 39 + 0x37 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::io_thread_t::`scalar deleting destructor'() + 0x2c bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::ctx_t::~ctx_t() Line 82 + 0x49 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::ctx_t::`scalar deleting destructor'() + 0x2c bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::ctx_t::terminate() Line 153 + 0x3d bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq_ctx_term(void * ctx_) Line 171 + 0xa bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq_ctx_destroy(void * ctx_) Line 242 C++
DataReader.dll! zmq::context_t::close() Line 309 + 0xe bytes C++
DataReader.dll! zmq::context_t::~context_t() Line 303 C++
MFC应用程序具有运行专门创建的DLL的机制。此DLL基于CWinApp,InitInstance成员函数中的所有DLL特定初始化代码和ExitInstance中的终止代码。所以this JIRA issue不应该是这种情况。
几天后,我发现该应用程序还依赖套接字作为ZMQ。因此,在它的生命周期结束时,ZMQ上下文正在等待关闭进程中所有打开的套接字,但MFC应用程序继续使用其打开的套接字。这就是zmq_ctx_destroy()函数永远挂起的原因。
答案 0 :(得分:-1)
此类案例的解决方案(当应用程序也使用套接字时,您需要添加一些基于ZMQ的功能)。 创建一个新流程。此过程将创建ZMQ上下文并发送/接收所有消息。来自dll的数据可以通过Windows消息或共享内存传递给该进程。