Linux 线程控制 —— 线程取消 pthread_cancel

线程退出pthread_exit只能终止当前线程,也就是哪个线程调用了pthread_exit,哪个线程就会退出;但是线程取消pthread_cancel ,不光可以终止自己,还可以终止其他线程。

==》自己终止自己,没问题!

==》主线程调用pthread_cancel来终止子线程,没问题!

==》子线程调用pthread_cancel来终止主线程,也没有问题!(只不过这种不大常见)


目录

1、认识 pthread_cancel 函数

(1) pthread_cancel 函数介绍

(2) pthread_cancel函数实际应用:子线程自我终止、子线程终止主线程

2、其他线程取消相关函数

(1) 取消点设置函数 pthread_testcancel (了解)

(2) 线程取消使能 pthread_setcancelstate(了解)

(3) 线程取消类型设置 pthread_setcanceltype(了解)


1、认识 pthread_cancel 函数

(1) pthread_cancel 函数介绍

参数是线程ID,也就是你希望终止哪个线程;成功返回0,失败返回一个错误码。pthread_cancel 使用的前提条件是 被终止的线程有取消点,即阻塞的系统调用如sleep函数

Linux 线程控制 —— 线程取消 pthread_cancel_第1张图片

(2) pthread_cancel函数实际应用:子线程自我终止、子线程终止主线程

==========================子线程自我终止==========================

子线程自我终止 和 主线程终止子线程的效果是一样的,这里就只演示子线程自我终止的情况,核心代码如下,此时需要留意一下返回值

Linux 线程控制 —— 线程取消 pthread_cancel_第2张图片

 测试结果如下,我们发现,子线程提前终止,居然还会有返回值,返回值是-1,其实-1在Linux中代表的就是 PTHREAD_CANCELED

Linux 线程控制 —— 线程取消 pthread_cancel_第3张图片

 站在OS的角度,结果如下

Linux 线程控制 —— 线程取消 pthread_cancel_第4张图片

 ==========================子线程终止主线程==========================

一般来说,不建议这么做,因为主线程会等待回收子线程,子线程退出就有人回收;但是子线程不会去回收主线程,所以主线程退出的时候,由于没有人回收,这个时候,主线程就会出现类似于“僵尸进程”的情况

Linux 线程控制 —— 线程取消 pthread_cancel_第5张图片

测试结果如下,我们会发现,主线程的旁边有一个 ,defunct是死者的意思,说明这个线程已经死了,类似于“僵尸进程”

Linux 线程控制 —— 线程取消 pthread_cancel_第6张图片

2、其他线程取消相关函数

(1) 取消点设置函数 pthread_testcancel (了解)

上面提到,被终止的线程必须要有取消点,如果没有取消点,这里可以自己手动设置一个取消点,这样的话无需 sleep 函数就可以实现线程取消了。函数声明如下:

Linux 线程控制 —— 线程取消 pthread_cancel_第7张图片

void* thread_run(void* args)
{
    pthread_testcancel();        // 设置取消点
}

int main(){
    pthread_t tid;
    pthread_create(&tid, NULL, thread_run, NULL);

    pthread_cancel(tid);        // 取消子线程
}

(2) 线程取消使能 pthread_setcancelstate(了解)

默认情况下,线程是可以被取消的,但是你如果不希望线程被取消,可以使用 pthread_setcancelstate 函数来禁止线程被取消,哪个线程要设置取消使能,那就放在哪个线程里。函数声明如下:

第一个参数state:设置线程是否取消。可选值如下:

  • PTHREAD_CANCEL_ENABLE:允许当前线程取消
  • PTHREAD_CANCEL_DISABLE:禁止当前线程被取消

第二个参数 oldstate:这是一个输出型参数,输出上一次线程的使能状态

void* thread_run(void* args)
{
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE);  // 此时该线程不可被取消(在取消点之前)

    pthread_testcancel();        // 设置取消点
    // ...
}

int main(){
    pthread_t tid;
    pthread_create(&tid, NULL, thread_run, NULL);

    pthread_cancel(tid);        // 取消子线程
}

(3) 线程取消类型设置 pthread_setcanceltype(了解)

线程取消类型有两种,一种是遇到取消点再取消线程;另一种是目标线程会立马取消。默认是遇到取消点再取消。函数声明如下:

Linux 线程控制 —— 线程取消 pthread_cancel_第8张图片

第一个参数 type:设置线程取消的类型。可选值如下:

  •  PTHREAD_CANCEL_DEFERRED等到取消点才取消
  • PTHREAD_CANCEL_ASYNCHRONOUS目标线程会立即取消

第二个参数 oldtype:输出型参数。返回上一次的取消类型。

你可能感兴趣的:(Linux,基础,java,开发语言)