pthread_cancel(3)

๐Ÿ’– pthread_cancel(3) โ€” the "hey bestie, you're done" signal ๐Ÿ’–

okay so this is from the Library Functions Manual, and it lives in the POSIX threads library โ€” that's libpthread, and you link it with -lpthread. periodt. ๐Ÿ’…


โœจ NAME โœจ

pthread_cancel โ€” send a cancelation request to a thread ๐Ÿซถ

๐Ÿ“š LIBRARY ๐Ÿ“š

POSIX threads library (libpthread, -lpthread)

๐ŸŒธ SYNOPSIS ๐ŸŒธ

#include <pthread.h>

int pthread_cancel(pthread_t thread);

๐Ÿ’œ DESCRIPTION ๐Ÿ’œ

So pthread_cancel() sends a cancelation request to the thread called thread. And here's the tea: whether and when the target thread actually reacts to that request? That depends on two attributes that are under the control of that thread itself โ€” its cancelability state and its cancelability type. Not you. Not the caller. The target thread's own vibes. ๐Ÿ™ˆ

A thread's cancelability state, which is set by pthread_setcancelstate(3), can be either enabled (that's the default for brand-new threads) or disabled. If a thread has cancelation disabled, then the cancelation request just sits there queued ๐Ÿช‘ until the thread enables cancelation. But if the thread has cancelation enabled, then its cancelability type is what decides when cancelation actually goes down.

A thread's cancelability type, which is set by pthread_setcanceltype(3), can be either asynchronous or deferred (deferred is the default for new threads). Asynchronous cancelability means the thread can be canceled at literally any time (usually immediately, but ngl the system does not guarantee this). Deferred cancelability means cancelation gets delayed until the thread next calls a function that's a cancelation point. There's a whole list of functions that are, or might be, cancelation points over in pthreads(7). go look, iykyk ๐Ÿ“–

When a cancelation request is actually acted on, here's the order of operations for thread โ€” and yes, it's in this exact order, no skipping:

  1. Cancelation clean-up handlers get popped (in the reverse of the order they were pushed) and called. (See pthread_cleanup_push(3).)
  2. Thread-specific data destructors get called, in an unspecified order. (See pthread_key_create(3).)
  3. The thread is terminated. (See pthread_exit(3).)

All of that happens asynchronously with respect to the pthread_cancel() call, so heads up: the return status of pthread_cancel() only tells the caller whether the cancelation request got successfully queued. That's it. It's not a receipt that the thread is gone. ๐Ÿ’€

After a canceled thread has terminated, joining with that thread using pthread_join(3) gets you PTHREAD_CANCELED as the thread's exit status. And honestly? Joining with a thread is the only way to know that cancelation has completed. the only way fr fr ๐Ÿ‘‘

๐ŸŽ€ RETURN VALUE ๐ŸŽ€

On success, pthread_cancel() returns 0; on error, it returns a nonzero error number.

๐Ÿ‘‘ ERRORS ๐Ÿ‘‘

  • ESRCH โ€” No thread with the ID thread could be found. gone, not found, ghosted ๐Ÿ’€

๐ŸŒˆ ATTRIBUTES ๐ŸŒˆ

For an explanation of the terms used in this section, see attributes(7).

  • Interface: pthread_cancel()
  • Attribute: Thread safety
  • Value: MT-Safe โœ…

(so she's MT-Safe bestie, you're fine)

โญ VERSIONS โญ

On Linux, cancelation is implemented using signals. Under the NPTL threading implementation, the first real-time signal (i.e., signal 32) is used for this purpose. On LinuxThreads, the second real-time signal is used, if real-time signals are available, otherwise SIGUSR2 is used. ๐Ÿ””

๐Ÿงš STANDARDS ๐Ÿงš

POSIX.1-2008.

๐ŸŒธ HISTORY ๐ŸŒธ

glibc 2.0 โ€” POSIX.1-2001.

๐Ÿ’– EXAMPLES ๐Ÿ’–

The program below creates a thread and then cancels it. The main thread joins with the canceled thread to check that its exit status was PTHREAD_CANCELED. Here's what happens when we run the program, shell session and all:

$ ./a.out
thread_func(): started; cancelation disabled
main(): sending cancelation request
thread_func(): about to enable cancelation
main(): thread was canceled

๐Ÿฆ‹ Program source ๐Ÿฆ‹

#include <err.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void *
thread_func(void *ignored_argument)
{
    int s;

    /* Disable cancelation for a while, so that we don't
       immediately react to a cancelation request.  */

    s = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
    if (s != 0)
        errc(EXIT_FAILURE, s, "pthread_setcancelstate");

    printf("%s(): started; cancelation disabled\n", __func__);
    sleep(5);
    printf("%s(): about to enable cancelation\n", __func__);

    s = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    if (s != 0)
        errc(EXIT_FAILURE, s, "pthread_setcancelstate");

    /* sleep() is a cancelation point.  */

    sleep(1000);        /* Should get canceled while we sleep */

    /* Should never get here.  */

    printf("%s(): not canceled!\n", __func__);
    return NULL;
}

int
main(void)
{
    pthread_t thr;
    void *res;
    int s;

    /* Start a thread and then send it a cancelation request.  */

    s = pthread_create(&thr, NULL, &thread_func, NULL);
    if (s != 0)
        errc(EXIT_FAILURE, s, "pthread_create");

    sleep(2);           /* Give thread a chance to get started */

    printf("%s(): sending cancelation request\n", __func__);
    s = pthread_cancel(thr);
    if (s != 0)
        errc(EXIT_FAILURE, s, "pthread_cancel");

    /* Join with thread to see what its exit status was.  */

    s = pthread_join(thr, &res);
    if (s != 0)
        errc(EXIT_FAILURE, s, "pthread_join");

    if (res == PTHREAD_CANCELED)
        printf("%s(): thread was canceled\n", __func__);
    else
        printf("%s(): thread wasn't canceled (shouldn't happen!)\n",
               __func__);
    exit(EXIT_SUCCESS);
}

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

pthread_cleanup_push(3), pthread_create(3), pthread_exit(3), pthread_join(3), pthread_key_create(3), pthread_setcancelstate(3), pthread_setcanceltype(3), pthread_testcancel(3), pthreads(7)


k that's the whole thing, you ate it bestie ๐Ÿซถ this page is from Linux man-pages 6.20, dated 2025-09-21, and it's pthread_cancel(3). mwah ๐Ÿ’‹

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms