Joining threads before program termination - c++

I have a vector of threads that I collect during the execution of my application. To avoid some nasty behavior, I'm trying to ensure every thread is completed when the main thread exits. I tried to call std::thread::join on each thread in the vector upon a termination event, but it seems to get stuck if the most recent thread hasn't finished its work and won't stop blocking even after it should. It's important to note that ThingMaker::CreateThing reads frames from a series of video files and writes them all to one video, so I know the thread should finish its work in less time than the length of the video clip being created.
std::vector<std::thread> threadList;
while (!done)
{
switch (triggerEvent)
{
case 'h': // Spawn new thread to make a thing "in the background"
{
ThingMaker next_thing = new ThingMaker();
threadList.push_back(std::thread(&ThingMaker::CreateThing, next_thing));
next_thing = NULL;
break;
}
case 't': // Terminate the application
{
std::vector<std::thread>::iterator threads;
for (threads = threadList.begin(); threads != threadList.end(); ++threads)
threads->join();
done = true;
break;
}
default: break;
}
}
If I send a 't' before the most recent thread has finished making the video clip and thus finished altogether, threads->join() blocks forever. However, if i wait for all video clips to be created, the application terminates. To my understanding, it should simply wait for the thread to finish its work and then let the main thread carry on - is this a misunderstanding?

There are two possibilities:
The thread simply hasn't finished yet. You can add logging to your code or use a debugger to see whether this is the case.
The thread that called join holds some lock that is preventing the other thread from finishing. Calling join waits for a thread to finish and cannot be safely called unless you're absolutely sure that thread that calls join holds no locks the other thread might need to acquire in order to finish. (Look closely at the call stack leading to the call to join to see if this is a posssibility.)

There are two issues in your code:
The join() on an active thread will wait that the thread is finished before continuing anything. So if you have no mechanism to to tell your threads to stop (e.g. a shared atomic variable), you'll wait forever.
Your threadlist vector is inside the while loop, so that it's a new list on every occurence. What happens to the thread that you have pushed into it ? It gets destroyed, and as join() wasn't called, it will terminate() your programme.

With std::thread you must ensure that each thread is made unjoinable (that typically means calling .join()), exactly once. Clearly, a call to .join() will wait for that thread to complete. Start a debug session and have a look what each of the threads are doing.

The code you have shown (which is still woefully incomplete and so we're just guessing) doesn't remove thread objects from the vector after you join them. That means you will try to rejoin an already joined thread on the next time through the loop. Trying to join a thread that is not joinable has undefined behaviour. It could block forever (because there is no such thread so it can never be joined).
You should either:
only try to join threads that are joinable:
case 't': // Terminate the application
{
for (auto& t : threadList)
if (t.joinable())
t.join();
done = true;
break;
}
or remove the threads from the list after they've been joined:
case 't': // Terminate the application
{
for (auto& t : threadList)
t.join();
threadList.clear();
done = true;
break;
}

Related

I am using threads to do two things at the same time but the second thread stops the main thread

I am using threads to do two things at the same time, the main thread is responsible for the program and the second thread is just to execute a function that function has a while loop that doesn't end unless the user presses a specific key on the keyboard.
// This function freezes an address value by assigning a value continuously
void SuperJump() {
DWORD OffsetBaseAddress = 0x1C85FC;
int value = 0;
while (true) {
if (GetAsyncKeyState(VK_NUMPAD4)) {
break;
}
Sleep(50);
WriteProcessMemory(hHandle, (LPVOID)(BaseAddress + OffsetBaseAddress), &value, sizeof(value), NULL);
}
}
int main() {
DWORD OffsetBaseAddress;
int value;
while (true) {
// ......
// ......
if (GetAsyncKeyState(VK_NUMPAD3)) {
std::thread th(&SuperJump);
th.join();
}
}
return 0;
}
The problem is when the second thread starts the main thread (program) doesn't respond to any key press until the second thread is finished.
I want the main thread (program) keeps responding (working) during the second thread work, is that possible or is there another way to implement my idea?
std::thread th(&SuperJump);
This creates a new execution thread.
th.join();
join() pauses the calling execution thread until the other execution thread finishes running. That's what join() does, so after a new execution thread gets created the original thread immediately waits until it's finished, accomplishing nothing much by doing that.
There are two ways of making the execution threads run concurrently.
Don't join the execution thread immediately. The std::thread object itself must exist as long as the execution thread is running. The usual rules of C++ that govern scoping and lifetime can be used to control the lifetime of this thread object, when it gets created and destroyed. Use the existing lifetime and scoping rules to implement whatever actual duration of this execution thread you want to have, and only when the main execution thread wants this thread to stop, only then join and then destroy it.
Detach the new execution thread, and let it execute detached. The original thread object may be destroyed, but the calling thread no longer has any controls over joining a detached thread. Once detached it cannot be joined any more.
The expected behavior of your program is not very clear from the shown code. You'll need to figure out, and map out the semantics of your execution thread, when exactly it needs to start and stop, and implemented whichever approach you conclude will work best here.

Multithreading a while loop in c++

I've started c++ (coming from a c# background), and in my program I need to run a while true loop, but since it is an imgui program the ui freezes up completely since I'm using Sleep() in the loop. I need to create a new thread but everything I've found online is just
std::thread nThread(Method);
nThread.join();
Now, the issue with this is it doesn't work at all since, I'm assuming, it's a while loop that's always running. I want to do the c++ equivalent of Thread thread = new Thread(method) and thread.Start(); in c#. If anyone can help me, I'd appreciate it.
t.join() waits for thread t to die. If you don't want the method that started the thread to wait for it, then don't join() it.
But note! The C++ library will get angry with you if you allow the thread object to be destroyed while the thread still is running. (The destructor will throw an exception.) If you want to tell the library, "Shut up! I know what I'm doing," you can detach the thread from the object. But usually it's a cleaner design if you can arrange for the object to live for as long as you need the thread to run.
Try a simple example and work from there.
void myFunc()
{
try
{
int x = 0;
while (x < 10)
{
sleep(1000);
std::cout<<"Thread is running"<<std::endl;
x++;
}
}
catch(Interrupted_Exception&) {
cout << "Caught Interrupted_Exception" << endl;
}
}
int main()
{
std::cout<<"Starting main"<<std::endl;
std::thread nThread(myFunc);
std::cout<<"Thread is running. Waiting for it to complete"<<std::endl;
nThread.interrupt();//in case the thread is sleeping
nThread.join();
std::cout<<"All done. Exiting"<<std::endl;
return 0;
}
Join means that the main thread has to wait for the worker thread. It's a way to ensure that the worker thread terminates before the caller. You only want to do that when you are terminating the program, in your case when the GUI is being close. Since at that time you want to tell the worker thread to stop right away, you call interrupt() on tell it to stop sleeping.
In the example, you can comment out the interrupt call so that the worker thread runs to completion.
There is no direct equivalent of that in the standard C++ library. When you use std::thread, the new thread starts immediately. You can simulate delayed start behaviour by making the thread stuck on a locked in advance mutex, then release mutex when you want the thread action to run actually. Aftwerwards you have to either join the thread or make it detached, otherwise std::thread destructor will throw an exception.
If you are on Windows, you can try to use Windows API directly (CreateThread() with flag CREATE_SUSPENDED, then ResumeThread() and finally posssibly TerminateThread() - if thread has sort of endless loop which never terminates in itself).
There is a way you can approach this and is using std::future and std::async with std::launch::async mode and throwing the function with the loop there.
std::future allows you to run a thread in the background and then after running give back the control to the parent thread so the program's flow can go as normal.
so you could have a boolean for the while and when std::future gives you back the control then you could modify this bool in the parent or main thread.

What happens to a thread, waiting on condition variable, that is getting joined?

I've got a class named TThreadpool, which holds member pool of type std::vector<std::thread>>, with the following destructor:
~TThreadpool() {
for (size_t i = 0; i < pool.size(); i++) {
assert(pool[i].joinable());
pool[i].join();
}
}
I'm confident that when destructor is called, all of the threads are waiting on a single condition variable (spurious wakeup controlled with always-false predicate), and joinable outputs true.
Reduced example of running thread would be:
void my_thread() {
std::unique_lock<std::mutex> lg(mutex);
while (true) {
my_cond_variable.wait(lg, [] {
return false;
});
# do some work and possibly break, but never comes farther then wait
# so this probably should not matter
}
}
To check what threads are running, I'm launching top -H. At the start of the program, there are pool.size() threads + 1 thread where TThreadpool itself lives. And to my surprise, joining these alive threads does not remove them from list of threads that top is giving. Is this expected behaviour?
(Originally, my program was a bit different - I made a simple ui application using qt, that used threadpool running in ui thread and other threads controlled by threadpool, and on closing the ui window joining of threads had been called, but QtCreator said my application still worked after I closed the window, requiring me to shut it down with a crash. That made me check state of my threads, and it turned out it had nothing to do with qt. Although I'm adding this in case I missed some obvious detail with qt).
A bit later, I tried not asserting joinable, but printing it, and found out the loop inside Threadpool destructor never moved further than first join - the behaviour I did not expect and cannot explain
join() doesn't do anything to the child thread -- all it does is block until the child thread has exited. It only has an effect on the calling thread (i.e. by blocking its progress). The child thread can keep running for as long as it wants (although typically you'd prefer it to exit quickly, so that the thread calling join() doesn't get blocked for a long time -- but that's up to you to implement)
And to my surprise, joining these alive threads does not remove them from list of threads that top is giving. Is this expected behaviour?
That suggests the thread(s) are still running. Calling join() on a thread doesn't have any impact on that running thread; simply the calling thread
waits for the called-on thread to exit.
found out the loop inside Threadpool destructor never moved further than first join
That means the first thread hasn't completed yet. So none of the other threads haven't been joined yet either (even if they have exited).
However, if the thread function is implemented correctly, the first thread (and all other threads in the pool) should eventually complete and
the join() calls should return (assuming the threads in the pool are supposed to exit - but this doesn't need to true in general.
Depending on application, you could simply make the threads run forever too).
So it appears there's some sort of deadlock or wait for some resource that's holding up one or more threads. So you need to run through a debugger.
Helgrind would be very useful.
You could also try to reduce the number of threads (say 2) and to see if the problem becomes reproducible/obvious and then you could increase the threads.

Thread coordination with WaitForSingleObject and CEvent in MFC

In one of my MFC applications there are several worker threads. Nature of these threads are as below:
Most of the threads execute their tasks once and wait for a condition to be true for further execution.
In few cases thread waits infinitely until the condition becomes true and in other cases it waits for certain time periods and based on the condition becomes true or expiry of the time period whichever is earlier, it takes some action and again starts waiting.
Threads have to run throughout the life cycle of the application but not necessarily working every moment.
Currently each thread is having an infinite loop, where it executes it's task; as each thread has to work throughout the application's life cycle, I don't want to close these threads every time and recreate. Inside the loop I have used WaitForSingleObject with an auto-reset CEvent for such thread coordination. CEvent objects are signaled from any thread or from UI thread.
In this context I have following queries:
i. Is the approach well justified for my requirement?
ii. Is there any significant overhead of using so many CEvent objects for the purpose.
Is there any better alternative?
iii. In some cases a thread waits infinitely for a CEvent object to be signalled and the object is only signalled from windows message handler after it receives a Message from another thread.The message is received through PostMessage. Here I'm concerned about loosing a message sent from a thread. If Message handler skips a message, it cannot state of the CEvent object and the waiting thread has to wait infinitely. What precautions have to be taken to avoid such situation ? Is there any better way to reconstruct the scheme ?
Please suggest me some better alternatives.
Your approach is fine. Don't worry about multiple CEvent objects. In your case you must have at least one event per thread.
I am not sure what method you use to exit the thread. But you may need additional CEvent object to detect whether you have to exit the thread gracefully.
So in this case you would use WaitForMultipleObjects in each thread (1 event would be to run or not, another event would be to exit the thread or not).
If there are too many threads, that I would suggest that you spawn child threads when ever required. The child thread would simply run once and exit. In the parent thread you would again wait to see which child thread must be run. You can detect which thread to spawn based on array of event objects. This approach will take up less system resources.
Use WaitForMultipleObjects instead of WaitForSingleObject. The first event in each event array should be a global CEvent that is set to shutdown the app. Each thread detects this event and exits cleanly by returning from the thread function.
After setting the shutdown event (typically in OnClose) use WaitForMultipleObjects on the thread handles to wait for all the secondary threads to close. This makes sure that any global data that the threads may be accessing remains allocated until the threads are gone.
In my application I'm using 10 to 12 worker threads only. I read somewhere that
when a thread calls a wait function, it enters into kernel mode from the user mode. It is bit costly because to enter the kernel mode, approximately 1000 processor cycles are required which may be too expensive in a concrete situation.
However, as goths and ScottMcP suggested, I'm using WaitForMultipleObjects instead of WaitForSingleObject in the following way to ensure graceful thread closure before cleaning up any resources used by the thread.
CEvent doWork,exitThread; //Auto reset events
CWinThread* MyThread;
UINT MyThreadFunction(LPVOID param);
BOOL CMyDlg::OnInitDialog()
{
//Other initialization code
MyThread=AfxBeginThread(MyThreadFunction, CMyDlg::GetSafeHwnd());
//Any other initialization code
return TRUE;
}
UINT MyThreadFunction(LPVOID param)
{
HANDLE waitEvents[2];
waitEvents[0]=doWork;
waitEvents[1]=exitThread;
while(true)
{
DWORD stat=::WaitForMultipleObjects(2, waitEvents, FALSE, INFINITE);
switch(stat)
{
case WAIT_OBJECT_0 + 0:
// doWork CEvent is signalled; proceed to do some work
break;
case WAIT_OBJECT_0 + 1:
//exitThread is signalled; so exit from this thread handler function
return 0;
case WAIT_FAILED:
// failure may be related to wrong handles passed for lpHandles
break;
case WAIT_TIMEOUT:
// not applicable here because dwMilliseconds parameter is set to INFINITE
break;
}
}
return 0;
}
CMyDlg::OnClose()
{
exitThread.SetEvent();
DWORD Stat=WaitForSingleObject(MyThread->m_hThread, INFINITE);
if(Stat==WAIT_OBJECT_0)
{
//Thread supposed to be Exited
//Cleanup allocated resources here
}
else if(Stat==WAIT_TIMEOUT)
{
//not applicable here
}
else if(Stat==WAIT_FAILED)
{
//Invalid thred handle passed or something else
}
EndDialog(0);
}
Please, do comment on my answer if anything wrong is detected or there is any scope of improvement.

Waiting for a std::thread to finish

I am trying to clean up gracefully on program termination, so I'm calling join() on a std::thread to wait for it to finish. This simply seems to block the main thread forever, but I don't understand why, because the worker thread is an (almost) empty loop like this:
void GameLoop::Run()
{
while (run)
{
// Do stuff...
}
std::cout << "Ending thread...\n";
}
I'm setting run to false before joining, of course. Now, I'm suspecting it's got something to do with it being a member function and being called upon object destruction. I'm creating the thread like this: runThread.reset(new thread(&GameLoop::Run, this));, where runThread is unique_ptr<std::thread> and a member of GameLoop. The join() call comes in the destructor of the GameLoop object.
Maybe the loop thread cannot finish if its object is in the process of being destroyed? According to the debugger the loop thread lingers on in the dark depths of msvcr120d.dll. If so, how would you handle it?
Beware: new to std::thread here!
Update: This is my call to join in the destructor:
run = false;
if (runThread->joinable())
{
runThread->join();
}
Update 2: If I remove the join() I get an exception raised by ~thread()!
Of course, when you join a thread that doesn't cause the thread to terminate. It simply blocks until that thread dies of natural (or unnatural) causes.
In order to clean up a multithreaded application gracefully, you need to somehow tell the worker thread that it is time to die, and then wait for the death to happen. The "wait for death to happen" part is what join is for.
Ahh, apparently there's a bug in the runtime library. Threads are not ended successfully in destructors of static objects according to this question. My GameLoop is a non-static object contained in a static GameSystem. I'll check whether this is true and update.
Yep, confirmed. Just my luck to hit a bug on first use!