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