Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 345
Tomas Avatar asked Dec 15 '14 12:12

Tomas


People also ask

Is a for loop thread safe?

No, for-each loop is just a compiler magic that is equivalent to iteration with Iterator for collection and with index for arrays. It does not add any other effects like thread safety.

Can a thread create more threads?

Yes. The typical problem, however, is that the work/threads are not constrained. Using the approach you have outlined, it's easy to spawn many threads and have an illogically high number of threads for the work which must be executed on a limited number of cores.


2 Answers

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. 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.

like image 193
Mike Seymour Avatar answered Sep 22 '22 10:09

Mike Seymour


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 detached, joined or moved. 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. Otherwise, you can put it into an std::vector<std::thread>, so that you can find it and join it sometimes later.

like image 25
James Kanze Avatar answered Sep 22 '22 10:09

James Kanze