With every thread some resources are associated like stack and thread local storage etc. 

When a thread exits ideally these resources should be reclaimed by process automatically. But that doesn’t happens always. It depends on which mode thread is running. A Thread can run in two modes i.e.

  • Joinable Mode
  • Detached Mode

Joinable Thread & pthread_join()

By default a thread runs in joinable mode. Joinable thread will not release any resource even after the end of thread function, until some other thread calls pthread_join() with its ID.

#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);

pthread_join() is a blocking call, it will block the calling thread until the other thread ends.

  • First parameter of pthread_join() is the ID of target thread.
  • Second parameter of pthread_join() is address of (void *) i.e. (void **), it will point to the return value of thread function i.e. pointer to (void *).

void * ptr = NULL;
// Wait for thread to exit
int err = pthread_join(threadId, &ptr);

pthread_join() will return non zero value in case of error.

Check out the following example of Joinable Thread,

#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 value from thread
	return new int(6);
}

int main()
{
	// Thread id
	pthread_t threadId;

	// Create a thread that will funtion 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

	void * ptr = NULL;
	std::cout << "Waiting for thread to exit" << std::endl;
	// Wait for thread to exit
	err = pthread_join(threadId, &ptr);
	if (err)
	{
		std::cout << "Failed to join Thread : " << strerror(err) << std::endl;
		return err;
	}

	if (ptr)
		std::cout << " value returned by thread : " << *(int *) ptr
				<< std::endl;

	delete (int *) ptr;
	return 0;
}

Output:
Thread Created with ID : 140702080427776
Waiting for thread to exit
Thread Function :: Start
Thread Function :: End
 value returned by thread : 6

Detached Thread & pthread_detach()

A Detached thread automatically releases it allocated resources on exit. No other thread needs to join it. But by default all threads are joinable, so to make a thread detached we need to call pthread_detach() with thread id i.e.

#include <pthread.h>
int pthread_detach(pthread_t thread);

Lets see how to use it,
int err = pthread_detach(threadId);

Also, as detached thread automatically release the resources on exit, therefore there is no way to determine its return value of detached thread function.
pthread_detach() will return non zero value in case of error.

Checkout complete example 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;
	std::cout << "Thread Function :: End" << std::endl;
	// Return value from thread
	return NULL;
}

int main()
{
	// Thread id
	pthread_t threadId;

	// Create a thread that will funtion 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

	err = pthread_detach(threadId);
	if (err)
		std::cout << "Failed to detach Thread : " << strerror(err) << std::endl;

	// Sleep for 2 seconds because if main function exits, then other threads will
	// be also be killed. Sleep for 2 seconds, so that detached exits by then
	sleep(2);

	std::cout << "Main function ends " << std::endl;
	return 0;
}

Output:
Thread Created with ID : 139703273027328
Thread Function :: Start
Thread Function :: End
Main function ends

Output can change on your system because both main and thread function are running in parallel.

If main function exits then all other threads will be exited.

To compile the above code use following command,

g++ example.cpp -lpthread