pthread_cancel函数用法详解
pthread_cancel函数简介
- 头文件包含
#include <pthread.h>
- 函数定义
int pthread_cancel(pthread_t thread );
- 编译链接选项
-pthread
pthread_cancel函数常见使用错误
- 链接错误
undefined reference to `pthread_cancel'
解决办法:添加链接选项
-pthread
- 编译错误
warning: implicit declaration of function ‘pthread_cancel’ [-Wimplicit-function-declaration]
解决办法:包含头文件
#include <pthread.h>
pthread_cancel函数详细描述
pthread_cancel ()函数向线程thread 发送取消请求,目标线程是否以及何时对取消请求做出反应取决于该线程控制的两个属性:可取消性state和type
线程的可取消状态(由pthread_setcancelstate (3)确定)可以是enabled(新线程的默认值)或disabled (如果线程已禁用取消),则取消请求将保持排队状态,直到线程启用取消。如果线程已启用取消,则其可取消性类型将确定何时发生取消。
线程的取消类型由pthread_setcanceltype (3)确定,可以是asynchronous或deferred(新线程的默认值)。异步可取消性意味着线程可以随时取消(通常是立即取消,但系统不保证这一点)。延迟的可取消性意味着取消将被延迟,直到线程下一次调用一个是"cancellation point" 的函数,在pthreads (7)中提供了一系列是或可能是取消点的函数
当执行取消请求时,thread将执行以下步骤(按以下顺序):
- 取消清理处理程序会弹出(与推送它们的顺序相反)并被调用。(参见pthread_cleanup_push (3))
- 以未指定的顺序调用线程特定的数据析构函数。(参见pthread_key_create (3))
- 线程终止。(参见pthread_exit (3))
对于pthread_cancel ()调用,上述步骤是异步进行的;pthread_cancel ()的返回状态仅仅通知调用者取消请求是否已成功排队。
取消的线程终止后,使用pthread_join (3)与该线程的联接将获得 PTHREAD_CANCELED 作为该线程的退出状态。(与线程连接是知道取消已完成的唯一方法。)
pthread_cancel函数返回值
成功时,pthread_cancel ()返回0;出错时,它返回一个非零错误号。
pthread_cancel函数错误码
- 找不到ID为thread的线程。
pthread_cancel函数其他说明
在Linux上,取消是使用信号实现的。在NPTL线程实现下,第一实时信号(即,信号32)用于此目的。在LinuxThreads上,如果实时信号可用,则使用第二个实时信号,否则使用 SIGUSR2 。
pthread_cancel函数使用举例
下面的程序创建一个线程,然后取消它。主线程与被取消的线程连接,以检查其退出状态是否为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) \e
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 don\(aqt
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\en");
sleep(5);
printf("thread_func(): about to enable cancellation\en");
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!\en");
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\en");
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\en");
else
printf("main(): thread wasn\(aqt canceled (shouldn\(aqt happen!)\en");
exit(EXIT_SUCCESS);
}
评论区