PTHREAD_CANCEL - Linux手册页

时间:2019-08-20 18:01:02  来源:igfitidea点击:

Linux程序员手册 第3部分
更新日期: 2020-06-09

名称

pthread_cancel-向线程发送取消请求

语法

#include <pthread.h>

int pthread_cancel(pthread_t thread);

Compile and link with -pthread.

说明

pthread_cancel()函数将取消请求发送到线程线程。目标线程是否以及何时响应取消请求取决于该线程控制下的两个属性:其可取消状态和类型。

pthread_setcancelstate(3)确定的线程的可取消状态可以启用(新线程的默认设置)或禁用。如果线程已禁用取消,则取消请求将一直排队,直到该线程启用取消为止。如果线程已启用取消,则其取消类型将确定何时发生取消。

pthread_setcanceltype(3)确定的线程取消类型可以是异步的也可以是延迟的(新线程的默认设置)。异步可取消性意味着可以随时(通常立即立即取消线程,但系统不对此进行保证)被取消。延迟可取消性意味着取消将被延迟,直到线程下一次调用作为取消点的函数为止。 pthreads(7)中提供了可能是或可能是取消点的函数列表。

当执行请求的取消操作时,线程将按照以下顺序执行以下步骤:

1.
取消清除处理程序被弹出(与它们被推的顺序相反)并被调用。 (请参阅pthread_cleanup_push(3)。)
2.
特定于线程的数据析构函数以未指定的顺序被调用。 (请参阅pthread_key_create(3)。)
3.
线程终止。 (请参阅pthread_exit(3)。)

上述步骤相对于pthread_cancel()调用是异步发生的; pthread_cancel()的返回状态仅通知调用方取消请求是否已成功排队。

取消的线程终止后,使用pthread_join(3)与该线程的联接获得PTHREAD_CANCELED作为线程的退出状态。 (加入线程是知道取消已完成的唯一方法。)

返回值

成功时,pthread_cancel()返回0;否则,返回0。如果出错,则返回非零错误号。

错误说明

ESRCH
找不到具有ID线程的线程。

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
pthread_cancel()Thread safetyMT-Safe

遵循规范

POSIX.1-2001,POSIX.1-2008。

备注

在Linux上,取消是使用信号实现的。在NPTL线程实现下,第一实时信号(即信号32)用于此目的。在LinuxThreads上,如果有实时信号,则使用第二个实时信号,否则使用SIGUSR2。

示例

下面的程序创建一个线程,然后将其取消。主线程与已取消线程一起加入,以检查其退出状态为PTHREAD_CANCELED。以下shell会话显示了运行程序时发生的情况:

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

Program source

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

#define handle_error_en(en, msg) \
        do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

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

    /* Disable cancellation for a while, so that we donaqt
       immediately react to a cancellation request */

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

    printf("thread_func(): started; cancellation disabled\n");
    sleep(5);
    printf("thread_func(): about to enable cancellation\n");

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

    /* sleep() is a cancellation point */

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

    /* Should never get here */

    printf("thread_func(): not canceled!\n");
    return NULL;
}

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

    /* Start a thread and then send it a cancellation request */

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

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

    printf("main(): sending cancellation request\n");
    s = pthread_cancel(thr);
    if (s != 0)
        handle_error_en(s, "pthread_cancel");

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

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

    if (res == PTHREAD_CANCELED)
        printf("main(): thread was canceled\n");
    else
        printf("main(): thread wasnaqt canceled (shouldnaqt happen!)\n");
    exit(EXIT_SUCCESS);
}

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/