zmq_ctx_destroy() 在 MFC dll 中挂起

zmq_ctx_destroy() hangs in MFC dll

本文关键字:MFC dll 挂起 ctx destroy zmq      更新时间:2023-10-16

我正在使用ZMQ (zmq.hpp)编写MFC应用程序的扩展。当我尝试从应用程序中卸载我的 DLL 时,zmq_ctx_destroy() 函数永远挂起。

我发现了一个类似的问题,但没有答案。

我尝试调试它,发现它在第一行的函数 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 中的终止代码。所以这个JIRA问题不应该是这种情况。

几天后,我发现该应用程序还依赖于套接字作为ZMQ。因此,在其生命周期结束时,ZMQ 上下文正在等待关闭进程中所有打开的套接字,但 MFC 应用继续使用其打开的套接字。这就是 zmq_ctx_destroy() 函数永远挂起的原因。

针对此类情况的解决方案(当应用程序也使用套接字并且您需要基于 ZMQ 添加一些功能时)。创建新流程。此过程将创建 ZMQ 上下文并发送/接收所有消息。来自dll的数据可以通过Windows消息或共享内存传递到该进程。