在循环中创建新线程是否安全?我试过这种方式:
std::thread thread(ClientLoop,clientSocket)
但是一旦函数返回它就会抛出错误。
while (true){
cout << "Waiting for new connections" << endl;
clientSocket = accept(listenSocket, nullptr, nullptr);
cout << "Client connected" << endl;
new thread(ClientLoop,clientSocket);
}
这种方式有效,但我想知道是否没有内存泄漏。感谢。
答案 0 :(得分:28)
一旦函数返回它就会抛出错误
实际上,您不能销毁可连接的线程对象。如果您以后无需等待线程完成,请将其分离:
std::thread thread(ClientLoop,clientSocket);
thread.detach();
// OK to destroy now
如果您稍后需要加入,那么您必须将其存储在循环之外的地方,例如
std::vector<std::thread> threads;
while (whatever){
clientSocket = accept(listenSocket, nullptr, nullptr);
threads.emplace_back(ClientLoop,clientSocket);
}
// later
for (std::thread & t : threads) {
t.join();
}
// OK to destroy now
threads.clear();
这种方式有效,但我想知道是否没有内存泄漏。
是的,那是漏洞。每个new
创建一个线程对象,然后丢弃指针而不删除它或将其指定给智能指针来处理。正如评论中所提到的,它不仅会泄漏内存,还会泄漏线程句柄,这在某些系统上是一种更稀缺的资源;所以一段时间后你可能会发现你无法启动更多的线程。
分离线程是让它在后台运行而不会泄漏的方法。这会导致线程在完成时释放其资源。
答案 1 :(得分:9)
在循环中创建线程没有问题,但有可能
如果它是循环结束时破坏它的问题
一个局部变量。要合法地破坏,一个线程对象
必须detach
编辑,join
编辑或移动。如果你的线程是
简单地“开火,忘记”,你永远不必
之后与它们同步(即使是干净的关机)
在创建它之后,只需在线程上调用std::thread::detach
。
否则,您可以将其放入std::vector<std::thread>
,所以
你可以找到它并在以后加入它。
答案 2 :(得分:5)
看起来好像你不想管理线程的生命周期(这几乎总是一个错误)。
如果你真的想这样做,就这样做了:
while (true){
cout << "Waiting for new connections" << endl;
clientSocket = accept(listenSocket, nullptr, nullptr);
cout << "Client connected" << endl;
thread t(ClientLoop,clientSocket);
t.detach(); // detach the actual thread from its std::thread handle
}