Multithreading in C++

Multithreading means two or more threads runs concurrently and each thread handles different tasks . When you login to Facebook page you can see live videos, you can comment or hit a like simultaneously. While you are commenting it will check for your spelling mistakes. This is the best example of multithreading. Multithreading environment gives you permission to run many activities simultaneously; different threads are responsible for different activities.

There are various uses of multithreading are:

  • Better resource utilization.
  • Simpler program design.
  • More responsive programs.

Thread

Thread is generally referred as light weight process. Each thread executes different parts of a program. Each thread shares memory, file descriptors and other system resources. In Linux, all thread functions are declared in <pthread.h>. It is not available in standard C++ library.

Creating Threads in Linux

  1. pthread_create() - It creates a new thread.

    Syntax: pthread_create(threadID,attr,start_routine,arg)

  2. ThreadID - unique identifier for each thread. ThreadID compared with other thread using pthread_equal().
  3. attr - Attribute object that may be used to set thread attributes. It controls interaction of thread with rest of the program.
  4. start_routine - The C++ routine that the thread will execute once it is created.
  5. arg - Single argument must be passed by reference as a pointer cast of type void. If no argument is to be passed, null can be used.
  6. pthread_exit() - It is used to terminate a thread.

Below is a sample program on creating threads in C++:

#include <iostream>
#include <pthread.h>
using namespace std;
char* str="Child thread";
void* func(void *str)
{
cout << "Child thread Created: "<<(char*)str;
}
int main()
{
s = ctime(&Time);
pthread_t t; //Step 1: Declaring thread
pthread_create(&t, NULL, &func, (void*)str); //Step 2: Calling create thread function
//pthread_create(threadID,attr,start_routine,arg)threadID =t,arg=(void*)str,atrr=Null,start_routine=func
cout<<"Main thread created"<<endl;
pthread_join(t,NULL);
exit(EXIT_SUCCESS); //Exiting after completion
return 0;
}

Output:

Main thread created
Child thread created: Child thread

Joining and Detaching Threads

There are two methods which we can use to join or detach threads−

  • join()

    Joining of thread is done by join() of thread class. It makes main thread and child thread inter dependent. Main thread terminates only after child threads i.e. main thread waits for child thread to complete execution.

    Syntax:

    Threadname.join();

    It returns once all functions are completed. A thread is not joinable when it is assigned to another thread or join() or detach() is called.

    Syntax:

    Threadname.joinable(); //It checks whether a thread is joinable. It returns bool value.
  • detach()

    The detach() function detaches a thread from the parent thread. It allows both main thread and child thread to execute independently.

    Syntax:

    Threadname.detach();

Below is a program demonstrating join() method:

#include <iostream>
#include <unistd.h> //To include sleep function
#include<ctime> //To get system time
#include <pthread.h>
using namespace std;
string s;
time_t Time = time(0);
void* func(void*)
{
s = ctime(&Time);
sleep(1); //Calls sleep function
cout << "Child thread Created "<<s<<endl;
}
int main()
{
s = ctime(&Time);
pthread_t t1[5]; //Step 1: Declaring thread
for(int i=0;i<5;i++)
{
cout<<"Thread T["<<i<<"] is Created "<<s<<endl;
pthread_create(&t1[i], NULL, &func, NULL); //Step 2: calling create thread function
pthread_join(t1[i],NULL); //Joining threads, main thread waits for child thread to complete
}
exit(EXIT_SUCCESS); //Exiting after completion
return 0;
}

Output:

Thread T[0] is Created Wed Nov 1 02:30:57 2017

Child thread Created Wed 1 02:30:57 2017]

Thread T[1] is Created Wed Nov 1 02:30:57 2017

Child thread Created Wed 1 02:30:57 2017

Thread T[2] is Created Wed Nov 1 02:30:57 2017

Child thread Created Wed 1 02:30:57 2017

Thread T[3] is Created Wed Nov 1 02:30:57 2017

Child thread Created Wed 1 02:30:57 2017

Thread T[4] is Created Wed Nov 1 02:30:57 2017

Child thread Created Wed 1 02:30:57 2017

Below is a program of using detach() instead of join() method:

#include <iostream>
#include <unistd.h> //To include sleep function
#include<ctime> //To get system time
#include <pthread.h>
using namespace std;
string s;
time_t Time = time(0);
void* func(void*)
{
s = ctime(&Time);
sleep(1); //Calls sleep function
cout << "Child thread Created "<<s<<endl;
}
int main()
{
s = ctime(&Time);
pthread_t t1[5]; //Step 1: Declaring thread
for(int i=0;i<5;i++)
{
cout<<"Thread T["<<i<<"] is Created "<<s<<endl;
pthread_create(&t1[i], NULL, &func, NULL); //Step 2: Calling create thread function
pthread_detach(t1[i]); //Step 3: main thread doesn't waits for child thread to complete
}
exit(EXIT_SUCCESS); //Exiting after completion
return 0;
}

Output:

Thread T[0] is Created Wed Nov 1 02:38:14 2017

Thread T[1] is Created Wed Nov 1 02:38:14 2017

Thread T[2] is Created Wed Nov 1 02:38:14 2017

Thread T[3] is Created Wed Nov 1 02:38:14 2017

Thread T[4] is Created Wed Nov 1 02:38:14 2017