简体   繁体   English

在循环中创建新线程是否安全?

[英]Is it safe to create new thread in a loop?

Is it safe to create new thread inside while loop? 在循环中创建新线程是否安全? I have tried this way: 我试过这种方式:

std::thread thread(ClientLoop,clientSocket)

But as soon as the function return it throws the error. 但是一旦函数返回它就会抛出错误。

while (true){
    cout << "Waiting for new connections" << endl;
    clientSocket = accept(listenSocket, nullptr, nullptr);
    cout << "Client connected" << endl;
    new thread(ClientLoop,clientSocket);                
}   

This way it works, but I wonder if there are no memory leaks. 这种方式有效,但我想知道是否没有内存泄漏。 Thanks. 谢谢。

as soon as the function return it throws the error 一旦函数返回它就会抛出错误

Indeed, you mustn't destroy a joinable thread object. 实际上,您不能销毁可连接的线程对象。 If you have no need to wait for the thread's completion later, then detach it: 如果您以后无需等待线程完成,请将其分离:

std::thread thread(ClientLoop,clientSocket);
thread.detach();
// OK to destroy now

If you will need to join it later, then you'll have to store it somewhere that persists beyond the loop, for example 如果你以后需要加入它,那么你必须将它存储在一个持续超出循环的地方,例如

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();

This way it works, but I wonder if there are no memory leaks. 这种方式有效,但我想知道是否没有内存泄漏。

Yes, that's leaky. 是的,那是漏洞。 Each new creates a thread object, and you discard the pointer without deleting it or assigning it to a smart pointer to take care of. 每个new创建一个线程对象,您丢弃指针而不删除它或将其指定给智能指针进行处理。 As mentioned in the comments, it not only leaks memory, but also thread handles, which on some systems are a more scarce resource; 正如评论中所提到的,它不仅会泄漏内存,还会泄漏线程句柄,这在某些系统上是一种更稀缺的资源; so after a while you might find that you can't launch any more threads. 所以一段时间后你可能会发现你无法启动更多的线程。

Detaching a thread is the way to leave it running in the background without leaking. 分离线程是让它在后台运行而不会泄漏的方法。 This causes the thread to release its resources when it finishes. 这会导致线程在完成时释放其资源。

There's no problem creating the thread in a loop, but there may be a problem destructing it at the end of the loop if it is a local variable. 在循环中创建线程没有问题,但如果它是局部变量,则可能在循环结束时破坏它。 To be legally destructed, a thread object must be detach ed, join ed or moved. 要合法销毁,必须detachjoin或移动线程对象。 If your threads are simply “fire and forget”, and you never have to synchronize with them later (even for a clean shutdown), then just call std::thread::detach on the thread after creating it. 如果您的线程只是“火上浇油”,并且您以后永远不必与它们同步(即使是干净的关闭),那么在创建它之后只需在线程上调用std::thread::detach Otherwise, you can put it into an std::vector<std::thread> , so that you can find it and join it sometimes later. 否则,您可以将它放入std::vector<std::thread> ,以便您可以在以后找到它并加入它。

it looks as if you don't want to have to manage the lifetime of the thread (this is almost always a mistake). 它看起来好像你不想管理线程的生命周期(这几乎总是一个错误)。

If you really want to do this, it's done this way: 如果你真的想这样做,那就是这样做的:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM