Click here to Skip to main content
14,447,309 members
Rate this:
Please Sign up or sign in to vote.
See more:
I am trying to understand some basics of multi threading. I have written a simple program as shown below. When the child thread invokes a call back function, a crash is seen in the main thread (here the scope of call back function is in main thread. That's what I understand the scope is. But I am guessing it is something related to scope that is leading to crash)

#include <iostream>
#include <thread>

using namespace std;

void t1_exec(void (*notfiy_func)());
void main_observer();

int main()
{
	std::thread t1(t1_exec, main_observer);
	int i = 0;
	while (i < 200)
	{
		i++;
		cout << "In main thread" << endl;
	}

	return (0);
}

void t1_exec(void (*notify_func)())
{
	int i = 0;
	while (i < 5)
	{
		i++;
		cout << "Inside T1" << endl;
	}

	notify_func();
	
}

void main_observer()
{
	cout << "Inside Observer" << endl;

	exit(1);
}


What I have tried:

Tried to increase the time of execution of main thread by increasing the number of loop (i.e increased i to 2000). Still didn't help stopping crash.
Posted
Updated 14-Dec-17 0:05am
v3
Comments
_duDE 14-Dec-17 5:00am
   
What is about void *notfiy_func() ? Where is it declared? I miss it in your code ...
Richard MacCutchan 14-Dec-17 5:10am
   
It is a parameter name to t1_exec.
Richard MacCutchan 14-Dec-17 5:05am
   
I just tried your code and it runs fine, no crash and both threads terminated normally.

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

A parent thread should always wait until child threads have terminated. To do this, use thread::join - C++ Reference[^]:
int main()
{
    std::thread t1(t1_exec, main_observer);
    cout << "In main thread" << endl;
    t1.join();
    cout << "Child thread has terminated" << endl;
    return (0);
}

But the most probable reason that your program crashes is that you call exit within your main_observer() function:
Calling this function destroys all objects with static duration: A program with multiple threads running shall not call exit (see quick_exit for a similar function that does not affect static objects).
   
v2
Comments
Member 13508014 14-Dec-17 5:18am
   
thread::join is it a blocking call? If it is so I may not want to use it. Because the intention is not to block main thread and allow it to do its work.
Jochen Arndt 14-Dec-17 5:38am
   
It is blocking but called just before returning (terminating the application) after all work is done. If you did not use it, the main thread (your application) may terminate while the child thread is still running. That is not a problem with your example but it will be when you have global or shared variables (child thread might access variables that does not exist anymore).

If you want such behaviour (child thread still active even when main thread might has terminated), you should detach the thread (see std::thread detach).

But never call exit() with multi-threaded applications. You might call std::terminate() to terminate a thread. But there is no reason in your case because the thread is terminated when returning from the worker function.
Member 13508014 14-Dec-17 9:23am
   
That would have been a perfect solution if it worked. But there is no success when thread::join() is called before return in main(). That clears my question that I had in my mind. If thread::join() is NOT executed, then how does it can effect. That is what it happens when join() is called before return right?

And when thread::join() is called before the while loop in main, main thread does not get a chance at all to execute the loop which is as expected.
Jochen Arndt 14-Dec-17 9:34am
   
I never said that using join would avoid the crash. I mentioned it, because that is the way to use threads (or use detach which is rather uncommon).

The main answer is this:
"But the most probable reason that your program crashes is that you call exit() within your main_observer() function".

However, Richard has mentioned the code is running for him. So it is most probably also compiler and OS dependant.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100