Multithreading in C++

Multithreading in C++ is a specialized form of multitasking in which it allows your computer to run two (or) more programs concurrently.  The thread classes and related functions are defined in the thread header file. There are two different types of multitasking are present. They are as follows:

  • Process-based
  • Thread-based

Multithreading in C++

Thread: In multithreaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread defines a separate path of execution.

1) Process-based

The process-based multitasking handles the concurrent execution of the programmers.

2) Thread-based

The thread-based multitasking deals with concurrent execution of pieces of the same program.

The C++ program uses POSIX. A POSIX thread or Pthreads provides API which is available on many Unix-like POSIX systems such as FreeBSD, NetBSD, GNU/Linux, Mac OS X, and Solaris.

Creating threads

Example:

#include <pthread.h>
pthread_create (thread, attr, start_routine, arg) 

Here, the pthread_create creates a new thread and makes it executable. This routine can be called any number of times from anywhere within your code.

Parameters Used in threads

Parameter Description
thread An opaque, unique identifier for the new thread returned by the subroutine
attr An opaque attribute object that may be used to set thread attributes. You can specify a thread attributes object or NULL for the default values.
start_routine The C++ routine that the thread will execute once it is created.
arg A single argument that may be passed to start_routine. It must be passed by reference as a pointer cast of type void. NULL may be used if no argument is to be passed.

Passing Arguments to Threads

You can pass any data type in a thread callback because it points to void.

Example:

#include<iostream>
#include<cstdlib>
#include<pthread.h>
using namespace std;
#define NUM_THREADS 5
struct thread_data {
   int  thread_id;
   char *message;
};

void *PrintHello(void *threadarg) {
   struct thread_data *my_data;
   my_data = (struct thread_data *) threadarg;

   cout << "Thread ID : " << my_data->thread_id ;
   cout << " Message : " << my_data->message << endl;

   pthread_exit(NULL);
}

int main () {
   pthread_t threads[NUM_THREADS];
   struct thread_data td[NUM_THREADS];
   int rc;
   int i;

   for( i = 0; i < NUM_THREADS; i++ ) {
      cout <<"main() : creating thread, " << i << endl;
      td[i].thread_id = i;
      td[i].message = "This is message";
      rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&td[i]);
      
      if (rc) {
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }
   pthread_exit(NULL);
}

Output:

main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Thread ID : 3 Message: This is a message
Thread ID: 2 Message: This is a message
Thread ID : 0 Message: This is a message
Thread ID: 1 Message: This is a message
Thread ID: 4 Message: This is a message