A thread ends in one of three ways: natural causes, an early exit, or sudden death. Yes, it’s exciting, but no more than any aspect of programming.
I suppose the normal way for a thread to die is along with its parent program. Because the thread is part of the same overall process, when the main program terminates so do any spawned threads.
A thread can also terminate early, as was demonstrated in last week’s Lesson. This trick is used to capture a thread’s return value.
Another way to rub out a thread is to kill it off. The pthread_cancel() function handles the assassination. Its sole argument is the pthread_t value of a launched and running thread. Poof! The thread is gone.
The following code launches a thread that runs an endless loop. The main program pauses twice: once just because and a second time to quit.
2022_06_18-Lesson-a.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *eternal(void *p)
{
for( ;; )
{
printf("On I go...\n");
sleep(1);
}
}
int main()
{
pthread_t thd;
int r;
puts("Launching endless thread...");
/* spawn the new thread */
r = pthread_create( &thd, NULL, eternal, NULL);
if( r!=0 )
{
perror("Thread");
exit(1);
}
puts("Press Enter just because");
getchar();
puts("Press Enter to quit");
getchar();
return(0);
}
Here’s a sample run, where I press the Enter key (twice), but wait until the thread first spews out its text:
Launching endless thread...
Press Enter just because
On I go...
On I go...
On I go...
Press Enter to quit
On I go...
On I go...
The following update to the code adds the pthread_cancel() function to terminate the thread after the first Enter key prompt:
2022_06_18-Lesson-b.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *eternal(void *p)
{
for( ;; )
{
printf("On I go...\n");
sleep(1);
}
}
int main()
{
pthread_t thd;
int r;
puts("Launching endless thread...");
/* spawn the new thread */
r = pthread_create( &thd, NULL, eternal, NULL);
if( r!=0 )
{
perror("Thread");
exit(1);
}
puts("Press Enter to kill the thread");
getchar();
pthread_cancel(thd);
puts("Thread terminated");
puts("Press Enter to quit");
getchar();
return(0);
}
The first prompt’s text (Line 29) is updated to direct the user to press Enter to kill the thread. The pthread_cancel() function removes it, followed by output confirming that the thread is dead. Here’s a sample run:
Launching endless thread...
Press Enter to kill the thread
On I go...
On I go...
On I go...
On I go...
Thread terminated
Press Enter to quit
It’s important that you not use pthread_cancel() haphazardly. You don’t want to suddenly cancel a thread in the middle of something, which may create an unstable or undesirable condition.
To protect a thread from cancelation, refer to the pthread_setcancelstate() and pthread_setcanceltype() functions. You can also use the pthread_testcancel() function to insert a safe cancellation point within a thread’s code.
A good web page for further research on the topic of multithreaded programming in C is found here:Multithreaded Programming Guide from Oracle.