The Thread Must Die!

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.

Leave a Reply