Linux多线程06-线程取消

pthread_cancel

描述:

pthread_cancel()函数向线程thread发送一个取消请求。目标线程对取消请求的响应取决于该线程控制的两个属性:其取消状态和类型。

一个线程的取消状态由pthread_setcancelstate(3)确定,可以启用(对于新线程而言是默认的)或禁用。如果一个线程已禁用取消,则取消请求会保留在队列中,直到线程启用取消。如果一个线程已启用取消,则其取消类型决定了何时进行取消。

线程的取消类型由pthread_setcanceltype(3)确定,可以是异步或延迟(对于新线程而言是默认的)。异步可取消性意味着线程可以随时被取消(通常是立即的,但系统不保证这一点)。延迟可取消性意味着取消将延迟到线程下次调用的函数是取消点。取消点的函数列表在pthreads(7)中提供。

取消点

POSIX.1 指定了某些函数必须成为取消点,而某些其他函数则可能成为取消点。如果一个线程可被取消,其取消类型为延迟类型,而该线程有一个挂起的取消请求,则当该线程调用一个是取消点的函数时,该线程将被取消。

当一个取消请求被执行时,对于线程(按照以下顺序)会发生以下步骤:

  1. 取消清理处理程序会被弹出(按照它们被推入的相反顺序)并调用。(参见 pthread_cleanup_push(3)。)
  2. 线程特定数据析构器按照未指定的顺序调用。(参见 pthread_key_create(3)。)
  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
posted @ 2023-06-26 08:53  言叶以上  阅读(53)  评论(0编辑  收藏  举报