In this article we will discuss how to create a thread in C or C++ using POSIX Thread Library on Linux.

Creating a thread will create a separate execution unit with in the same process. Each thread will have its own,

  • Stack
  • Thread ID
  • Program counter
  • Thread Local Storage

Each of thread shares the process address space and can access heap, global and static variables. POSIX Thread library provides various functions to create and control threads.

Create thread using pthread_create()

Main function is also a thread. Now suppose we have a function that we want to run in parallel to main function i.e.

void * threadFunc(void * arg)
{
	std::cout << "Thread Function :: Start" << std::endl;
	// Sleep for 2 seconds
	sleep(2);
	std::cout << "Thread Function :: End" << std::endl;
	return NULL;
}

POSIX provides pthread_create() API to create a thread i.e.
#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

pthread_create() accepts 4 arguments i.e.

  1. Pointer of the Thread ID, it will update the value in it.
  2. Attributes to set the properties of thread.
  3. Function pointer to the function that thread will run in parallel on start. This function should accept a void * and return void * too.
  4. Arguments to be passed to function.

So, now let’s call pthread_create() by passing function pointer and other arguments i.e.

// Thread id
pthread_t threadId;

// Create a thread that will function threadFunc()
int err = pthread_create(&threadId, NULL, &threadFunc, NULL);
// Check if thread is created sucessfuly

pthread_create() returns the error code to specify the result of thread creation request. If thread is created successfully then it will return 0. Where as, if thread creation is failed it will return error code to specify the error. We can use strerror() to get the detail of error.
if (err)
	std::cout << "Thread creation failed : " << strerror(err);
else
	std::cout << "Thread Created with ID : " << threadId << std::endl;

Main function and other created threads runs in parallel. But when main function ends, complete process exits and all the other thread will also be terminated. Therefore, in main function before ending we should wait for other threads to exit.

POSIX Library provides a function for it i.e. pthread_join() to wait for other thread to exit.

// Wait for thread to exit
err = pthread_join(threadId, NULL);
// check if joining is sucessful
if (err)
	std::cout << "Failed to join Thread : " << strerror(err) << std::endl;

It accepts a thread ID and pointer to store the return value from thread. We will provide more details on joining and detaching threads in next article.

Complete example is as follows,

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>

#include <unistd.h>

void * threadFunc(void * arg)
{
	std::cout << "Thread Function :: Start" << std::endl;
	// Sleep for 2 seconds
	sleep(2);
	std::cout << "Thread Function :: End" << std::endl;
	return NULL;
}
int main()
{

	// Thread id
	pthread_t threadId;

	// Create a thread that will function threadFunc()
	int err = pthread_create(&threadId, NULL, &threadFunc, NULL);
	// Check if thread is created sucessfuly
	if (err)
	{
		std::cout << "Thread creation failed : " << strerror(err);
		return err;
	}
	else
		std::cout << "Thread Created with ID : " << threadId << std::endl;

	// Do some stuff in Main Thread

	std::cout << "Waiting for thread to exit" << std::endl;
	// Wait for thread to exit
	err = pthread_join(threadId, NULL);
	// check if joining is sucessful
	if (err)
	{
		std::cout << "Failed to join Thread : " << strerror(err) << std::endl;
		return err;
	}

	std::cout << "Exiting Main" << std::endl;

	return 0;
}

Output:
Thread Created with ID : 140054120654592
Waiting for thread to exit
Thread Function :: Start
Thread Function :: End
Exiting Main

To compile the above code use following command,

g++ example.cpp -lpthread