• 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是死者的意思,说明这个线程已经死了,类似于“僵尸进程”

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

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

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

    1. void* thread_run(void* args)
    2. {
    3. pthread_testcancel(); // 设置取消点
    4. }
    5. int main(){
    6. pthread_t tid;
    7. pthread_create(&tid, NULL, thread_run, NULL);
    8. pthread_cancel(tid); // 取消子线程
    9. }

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

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

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

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

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

    1. void* thread_run(void* args)
    2. {
    3. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE); // 此时该线程不可被取消(在取消点之前)
    4. pthread_testcancel(); // 设置取消点
    5. // ...
    6. }
    7. int main(){
    8. pthread_t tid;
    9. pthread_create(&tid, NULL, thread_run, NULL);
    10. pthread_cancel(tid); // 取消子线程
    11. }

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

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

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

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

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

  • 相关阅读:
    实现数据全字段搜索
    BMP编程实践1:C语言实现bmp位图分析与创建
    消费者偏移量_consumer_offsets相关解析
    HTTP超文本传输协议
    Make 详解
    delphi 使用TFlowPanel容器,实现对内含控件进行自动排版
    day1_QT
    web3.0学习入门7:深入学习Web3.0
    java.lang.ClassNotFoundException:如何解决
    语音合成 - TTS pyttsx3
  • 原文地址:https://blog.csdn.net/challenglistic/article/details/128142874