我不知道如何在线程完成时正确清理在 std::jthread 中创建的 zmq socket_t。
Bellow 是一个测试用例函数,它创建一个推送套接字,等待一点然后断开连接并关闭套接字(等待可以用发送替换,行为是相同的):
void async_func(std::stop_token& stoken, zmq::context_t* _context)
{
std::string _zmq_ipc_push_socket_name("ipc:///tmp/p3pushpull");
zmq::socket_t push_socket(*_context, zmq::socket_type::push);
push_socket.connect(_zmq_ipc_push_socket_name.c_str());
std::this_thread::sleep_for(std::chrono::milliseconds(500));
push_socket.disconnect(_zmq_ipc_push_socket_name.c_str());
push_socket.close();
}
该函数在主线程中调用:
#include <thread>
#include <memory>
#include "zmq.hpp"
#include "zmq_addon.hpp"
int main(int argc, char **argv) {
zmq::context_t _context = zmq::context_t(1);
std::shared_ptr<std::jthread> async_call_thread;
for (size_t idx = 0; idx < 10; idx++)
{
// jthread creation
async_call_thread = std::make_shared<std::jthread>([this](std::stop_token stoken){
if (stoken.stop_requested()) return;
async_func(stoken, &_context);
});
if (async_call_thread)
{
if (async_call_thread->joinable())
{
async_call_thread->request_stop();
async_call_thread->join();
}
async_call_thread.reset();
}
}
return 0;
}
我的问题是,当我查看 GDB 的线程管理时,我看到,正如预期的那样,创建了两个线程(一个用于 jthread,一个用于套接字)。然而,一旦线程被加入并重置,只有jthread退出。与套接字创建相对应的延迟线程会累积,只有在主线程结束后才会退出。
这显然是一个问题,如果我使用 1000 个线程,这可能会产生一个大问题。即使我只创建套接字(没有连接)而不是关闭它,我仍然遇到问题。
如何确保 jthread 完成后,与创建和关闭的套接字对应的线程被清理?
zmq 内部线程与当前
context
相关联,它们在 context
的析构函数中被销毁,这发生在 main
的末尾,它们的数量受到传递到上下文构造函数中的线程数量的限制.