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函数

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

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

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

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

 站在OS的角度,结果如下

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

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

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

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

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

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

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(了解)

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

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

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

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

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值