thread::join [Advanced] - What will happen if we call join again on same thread.

Question -3: What will happen if we call join again on same thread?

It shall lead us to crash if not handled properly. Let check with following example and then will see best practice to use join()

Case-1: Exception is not caught therefore lead of Abort.

Case-2: Exception is caught properly lead to normal execution and termination.

Case-3: Best practice to use join(), is to check with whether it is joinable() or not

Case-1: Join called again

Case-2: Join called with try-catch

#include<iostream>
#include<thread> //Thread Header
#include<chrono>

using namespace std;

//actual task to be performed
//by our thread


void displayActivity()
{
cout<<"www.techsujhav.com : "<<endl;
}

int main()
{
   cout<<"Going to start thread"<<endl;
     {//New scope started.
        std::thread t_obj(displayActivity);

      cout<<"Before Join, (ACTIVE) joinable="              <<t_obj.joinable()<<endl;

      t_obj.join();

      cout<<"After Join, (ACTIVE) joinable="                <<t_obj.joinable()<<endl<<endl;

        //..................................
        //..................................

       //Large code is written
       //By-mistake if programmer calls join again()

        //................................
       //................................


       t_obj.join();
       cout<<"Going out of scope"<<endl;

     }

     cout<<"Main Exit"<<endl;
     return 0;
}
#include<iostream>
#include<thread> //Thread Header
#include<chrono>

using namespace std;

//actual task to be performed
//by our thread


void displayActivity()
{
cout<<"www.techsujhav.com : "<<endl;
}

int main()
{
   cout<<"Going to start thread"<<endl;
    {//New scope started.
      std::thread t_obj(displayActivity);

     cout<<"Before Join, (ACTIVE) joinable=" <<t_obj.joinable()<<endl;

     t_obj.join();

     cout<<"After Join, (ACTIVE) joinable=" <<t_obj.joinable()<<endl<<endl;


    //........................
    //........................

    //Large code is written
    //By-mistake if programmer calls join again()

    //........................
    //........................


    try
    {
        t_obj.join();
    }
    catch(std::exception& e)
    {
       cout<<"Exception :: "<<e.what()
        <<endl;
    }
    catch(...)
    {
       cout<<"Exception"<<endl;
    }
    cout<<"Going out of scope"<<endl;
  }
  cout<<"Main Exit"<<endl;
  return 0;
}

$./join

Going to start thread

Before Join, (ACTIVE) joinable=1

www.techsujhav.com :

After Join, (ACTIVE) joinable=0

 

terminate called after throwing an instance of 'std::system_error'

  what():  Invalid argument

Aborted

$ ./join

Going to start thread

Before Join, (ACTIVE) joinable=1

www.techsujhav.com :

After Join, (ACTIVE) joinable=0

 

Exception :: Invalid argument

Going out of scope

Main Exit


Case-3: Best practice to use join(), is to check with whether it is joinable() or not

 Best Practice: Is to check whether it is joinable() or not

#include<iostream>

#include<thread> //Thread Header
#include<chrono>

using namespace std;

//actual task to be performed
//by our thread

void displayActivity()
{
    cout<<"www.techsujhav.com : "<<endl;
}

int main()
{
        cout<<"Going to start thread"<<endl;
        {//New scope started.
                std::thread t_obj(displayActivity);
                cout<<"Before Join, (ACTIVE) joinable=" <<t_obj.joinable()<<endl;
    
                if(t_obj.joinable())
                {
                    t_obj.join();
                }
                else
                    cout<<"Not-Valid to call join() on thread object"<<endl;


             cout<<"After Join, (ACTIVE) joinable=" <<t_obj.joinable()<<endl;
                //...........................................
                //...........................................
                //Large code is written
                //By-mistake if programmer calls join again()
                //.........................................
                //.........................................

                try
                {
                        if(t_obj.joinable())
                        {
                                t_obj.join();
                        }
                        else
                         cout<<"Not-Valid to call join() on thread object"<<endl;

                }
                catch(std::exception& e)
                {
                        cout<<"Exception :: "<<e.what()<<endl;
                }
                catch(...)
                {
                    cout<<"Exception"<<endl;
                }
                cout<<"Going out of scope"<<endl;
        }
        cout<<"Main Exit"<<endl;
        return 0;
}

 $./join



Going to start thread
Before Join, (ACTIVE) joinable=1
www.techsujhav.com :
After Join, (ACTIVE) joinable=0

Not-Valid to call join() on thread object
Going out of scope
Main Exit



Question:-1, Why do we need to call join() on thread object, although created thread has already finished its task?

Question:-2, Why does program lead to abort if join() is not called?


Question-4: Can we reuse that same thread object for different tasks after join()?


PREV:: Why do we need to call join()?


Your Comments /Suggestions & Questions are always welcome.
We would like to help you with best of our knowledge.
So feel free to put Questions.

No comments:

Post a Comment