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.
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.
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.
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.
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. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With