pthread_exit - terminate calling thread
void pthread_exit(void *retval)
Terminate the calling thread and return a value via retval. The return value is used by pthread_join. It also calls clean-up handlers and destructors for thread-specific data to do the cleanup activity.
Pthread_exit is implicitly called when a thread returns from its start function. If the application functionality needs, it can also be called explicitly to exit from a function other than start function.
When pthread_exit is used in the main thread as a replacement for exit (), will keep the main thread in zombie(defunct) status until all other threads exit. It will allow other threads to continue running. Since main thread exits after pthread_exit, it’s not possible to check the return status of threads and do clean-up after a pthread_exit call() as main thread exits. This is not a replacement for pthread_join. It should not be used as a single command to wait for all the threads.
Calling exit in any thread will terminate the process. All threads are terminated irrespective of which thread calls exit routine. A similar effect is when a signal is received which has the default action to terminate a process. In that case, all threads terminate, irrespective of which thread received signal.
void pthread_exit(void *retval)
Terminate the calling thread and return a value via retval. The return value is used by pthread_join. It also calls clean-up handlers and destructors for thread-specific data to do the cleanup activity.
Pthread_exit is implicitly called when a thread returns from its start function. If the application functionality needs, it can also be called explicitly to exit from a function other than start function.
A simple example
In this example using different global variables to return from the thread and to access it in the main thread using pthread_join(3). This shows the copying of data from pthread_exit(3) to pthread_join(3).
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
void *functionC(void *);
int *retVal;
int *ret;
int main()
{
int rc;
pthread_t th;
ret = (int *) malloc(sizeof(int));
*ret = 5;
if(rc = pthread_create(&th, NULL, &functionC, NULL))
{
printf("Thread creation failed, return code %d, errno %d", rc, errno);
}
pthread_join(th, (void**)&ret);
printf("Return value from thread = %d\n", *ret);
return 0;
}
void *functionC(void *)
{
retVal = (int *) malloc(sizeof(int));
*retVal = 1;
printf("Checking pthread_exit\n");
return (void*) retVal;
}
// Output of the above code
Checking pthread_exit
Return value from thread = 1
Using pthread_exit in main
When pthread_exit is used in the main thread as a replacement for exit (), will keep the main thread in zombie(defunct) status until all other threads exit. It will allow other threads to continue running. Since main thread exits after pthread_exit, it’s not possible to check the return status of threads and do clean-up after a pthread_exit call() as main thread exits. This is not a replacement for pthread_join. It should not be used as a single command to wait for all the threads.
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
void *functionC(void *);
int main()
{
int rc;
pthread_t th;
if(rc = pthread_create(&th, NULL, &functionC, NULL))
{
printf("Thread creation failed, return code %d, errno %d", rc, errno);
}
printf("Main thread %lu: Sleeping for 20 seconds\n", pthread_self());
fflush(stdout);
sleep(20);
pthread_exit(NULL);
printf("Main thread %lu: This will not be printed\n", pthread_self());
exit(0);
}
void *functionC(void *)
{
printf("Thread %lu: Sleeping for 20 second\n", pthread_self());
sleep(20);
printf("Thread %lu: Came out of first and sleeping again\n", pthread_self());
sleep(20);
printf("CThread %lu: Came out of second sleep\n", pthread_self());
}
// Output of the above code
Main thread 140166909204288: Sleeping for 20 seconds
Thread 140166900684544: Sleeping for 20 second
Thread 140166900684544: Came out of first and sleeping again
CThread 140166900684544: Came out of second sleep
// ps output
root@xxxx-VirtualBox:~/pthread_tst# ps -elfT |grep a.out
0 S root 9530 9530 9496 0 80 0 - 3722 hrtime 17:31 pts/1 00:00:00 ./a.out
1 S root 9530 9531 9496 0 80 0 - 3722 hrtime 17:31 pts/1 00:00:00 ./a.out
0 S root 9537 9537 2182 0 80 0 - 5384 pipe_w 17:31 pts/0 00:00:00 grep --color=auto a.out
root@xxxx-VirtualBox:~/pthread_tst# ps -elfT |grep a.out
0 Z root 9530 9530 9496 0 80 0 - 0 - 17:31 pts/1 00:00:00 [a.out] <defunct>
1 S root 9530 9531 9496 0 80 0 - 4258 hrtime 17:31 pts/1 00:00:00 ./a.out
0 S root 9539 9539 2182 0 80 0 - 5384 pipe_w 17:31 pts/0 00:00:00 grep --color=auto a.out
Using exit in thread
Calling exit in any thread will terminate the process. All threads are terminated irrespective of which thread calls exit routine. A similar effect is when a signal is received which has the default action to terminate a process. In that case, all threads terminate, irrespective of which thread received signal.
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
void *functionC(void *);
int main()
{
int rc;
pthread_t th;
if(rc = pthread_create(&th, NULL, &functionC, NULL))
{
printf("Thread creation failed, return code %d, errno %d", rc, errno);
}
printf("Main thread %lu: Sleeping for 20 seconds\n", pthread_self());
sleep(20);
printf("Main thread %lu: Came out of sleep, join thread\n", pthread_self());
pthread_join(th, NULL);
printf("Main thread %lu: Thread joined\n", pthread_self());
return 0;
}
void *functionC(void *)
{
printf("Thread %lu: Sleep for 10 seconds\n", pthread_self());
sleep(10);
printf("Thread %lu: Exiting from functionC\n", pthread_self());
exit(0);
}
// Output of the above code: Second printf in main thread is not seen
// as process exits after call to exit(3).
Main thread 139865285744448: Sleeping for 20 seconds
Thread 139865277224704: Sleep for 10 seconds
Thread 139865277224704: Exiting from functionC
Note on pthread_exit():- The function has no return value and it always succeeds.
- Process shared resources like mutexes, condition variables are not released after calling pthread_exit. They are released when a process exits.
- If you don't want to use the exit status of the thread and the function return type is not void *, some compiler may not give an error. However, when the thread returns from start function, pthread_exit will still copy return status to some address. It may cause a bug difficult to identify.
No comments:
Post a Comment