Linux多线程06-线程取消
pthread_cancel
描述:
pthread_cancel()函数向线程thread发送一个取消请求。目标线程对取消请求的响应取决于该线程控制的两个属性:其取消状态和类型。
一个线程的取消状态由pthread_setcancelstate(3)确定,可以启用(对于新线程而言是默认的)或禁用。如果一个线程已禁用取消,则取消请求会保留在队列中,直到线程启用取消。如果一个线程已启用取消,则其取消类型决定了何时进行取消。
线程的取消类型由pthread_setcanceltype(3)确定,可以是异步或延迟(对于新线程而言是默认的)。异步可取消性意味着线程可以随时被取消(通常是立即的,但系统不保证这一点)。延迟可取消性意味着取消将延迟到线程下次调用的函数是取消点。取消点的函数列表在pthreads(7)中提供。
取消点
POSIX.1 指定了某些函数必须成为取消点,而某些其他函数则可能成为取消点。如果一个线程可被取消,其取消类型为延迟类型,而该线程有一个挂起的取消请求,则当该线程调用一个是取消点的函数时,该线程将被取消。
当一个取消请求被执行时,对于线程(按照以下顺序)会发生以下步骤:
- 取消清理处理程序会被弹出(按照它们被推入的相反顺序)并调用。(参见 pthread_cleanup_push(3)。)
- 线程特定数据析构器按照未指定的顺序调用。(参见 pthread_key_create(3)。)
- 线程被终止。(参见 pthread_exit(3)。)
上述步骤与 pthread_cancel() 调用异步发生;pthread_cancel() 的返回状态仅告知调用者取消请求是否已成功排队。
在已终止的已取消线程之后,使用 pthread_join(3) 进行线程连接会获得 PTHREAD_CANCELED 作为线程的退出状态。(连接线程是知道取消已完成的唯一方法。)
#include <pthread.h>
int pthread_cancel(pthread_t thread);
功能: 取消线程(让线程终止)
取消某个线程,可以终止某个线程运行,但不是立刻终止;
而是当子线程执行到一个取消点, 线程才会终止
取消点: 系统规定的一些系统调用,
可以粗略理解为从用户区到内核区的切换, 这个位置成为取消点
Compile and link with -pthread.
示例代码
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void* callback(void* arg){
printf("child thread id: %ld\n",pthread_self());
int i = 0;
for(; i<5; i++){
printf("child: %d\n", i); //取消点
}
return NULL;
}
int main(){
pthread_t tid;
int ret = pthread_create(&tid, NULL, callback, NULL);
if(ret!=0){
char* errstr = strerror(ret);
printf("error_create: %s\n",errstr);
}
int i = 0;
for(; i<5; i++){
printf("main: %d\n", i);
}
//输出主线程和子线程ID
printf("tid: %ld, main thread id: %ld\n",tid,pthread_self());
//取消线程
pthread_cancel(tid); //子线程还没执行完就结束了
pthread_exit(NULL);
return 0;
}
运行
main: 0
main: 1
main: 2
main: 3
main: 4
tid: 140533913827072, main thread id: 140533922215744
child thread id: 140533913827072
child: 0
child: 1
child: 2
child: 3
child: 4