• Linux下多线程编程之——线程取消


      线程除了运行完毕后正常退出外,还可以被撤销,使得线程中途退出并释放资源

    一、线程取消函数pthread_cancel():

      1、输入参数:线程名称,函数向指定的线程发送终止信号

      2、返回参数:发送成功 0, 否则为非 0

      3、附加应用:pthread_join(),发送成功也无法保证线程就会终止,因此,调用pthread_cancel()函数后,常常继续调用pthread_join(),等待指定线程退出后,再次继续执行

    二、设置线程对cancel的反应函数pthread_setcancelstate():

      1、第一个参数:常量PTHREAD_CANCEL_ENABLE、设置线程可以cancel,常量PTHREAD_CANCEL_DISABLE、说明线程不可以cancel
      
    2、第二个参数:老的状态,当不为NULL时保存cancel状态,为线程恢复做好准备

    三、设置线程取消时机的函数pthread_setcanceltype():

      1、第一个参数:常量PTHREAD_CANCEL_DEFERRED、设置线程运行至下一个取消点退出,常量PTHREAD_CANCEL_ASYNCHRONOUS、说明线程立即退出
      2、第二个参数:老的状态,当不为NULL时保存原来的动作类型,为线程恢复做好准备

      3、pthread_testcancel()函数检查本线程是否处于cancel状态

    四、代码test7_4.c

    1 //This is c program code!                                                                                                                      
     2 /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
     3   * 文档信息: *** :~/test7_4.c
     4   * 版权声明: *** :(魎魍魅魑)MIT
     5   * 联络信箱: *** :guochaoxxl@163.com
     6   * 创建时间: *** :2020年11月17日的下午07:25
     7   * 文档用途: *** :数据结构与算法分析-c语言描述
     8   * 作者信息: *** :guochaoxxl(http://cnblogs.com/guochaoxxl)
     9   * 修订时间: *** :2020年第46周 11月17日 星期二 下午07:25 (第322天)
    10   * 文件描述: *** :自行添加
    11  * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/
    12 #include <stdio.h>
    13 #include <pthread.h>
    14 
    15 #define MAXTHREADS 3
    16     
    17 void *myComprint(void *iData){
    18     int oldState;
    19     int oldType;
    20     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldState);
    21     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldType);
    22     int *data = (int *)(iData);
    23     for(int i = 0; i < *data; i++){
    24         if((i % 250) == 0){
    25             printf("%d print: %d
    ", *data, i);
    26             pthread_testcancel();
    27         }
    28     }
    29 }       
    30         
    31 void *myComadd(void *iData){
    32     int oldState;
    33     int oldType;
    34     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldState);
    35     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldType);
    36     int sum = 0;
    37     int *data = (int *)(iData);
    38     for(int i = 1; i < *data; i++){
    39         sum += i;
    40         printf("%d add %d
    ", i, sum);
    41     }
    42 }
    43 
    44 void *myCommul(void *iData){
    45     int oldState;
    46     //int oldType;
    47     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
    48     int sum = 1;
    49     int *data = (int *)(iData);
    50     for(int i = 1; i <= *data; i++){
    51         sum *= i;
    52         printf("%d mul %d
    ", i, sum);
    53     }
    54 }
    55 
    56 int main(int argc, char **argv)
    57 {
    58     pthread_t threads[MAXTHREADS];
    59     void *status;
    60     int n1 = 25;
    61     int n2 = 10000;
    62 
    63     pthread_create(&(threads[0]), NULL, myComprint, &n2);
    64     pthread_create(&(threads[1]), NULL, myComadd, &n1);
    65     pthread_create(&(threads[2]), NULL, myCommul, &n1);
    66 
    67     for(int i = 0; i <MAXTHREADS; i++){
    68         pthread_cancel(threads[i]);                                                                                                            
    69     }
    70     for(int i = 0; i < MAXTHREADS; i++){
    71         pthread_join(threads[i], &status);
    72         if(status == PTHREAD_CANCELED){
    73             printf("thread %d 已经取消!
    ", i);
    74         }else{
    75             printf("thread %d 不能被取消!
    ", i);
    76         }
    77     }
    78 
    79     return 0;
    80 }  

     五、线程清理

      1、线程退出是有时需要清理所占资源,线程清理函数pthread_cleanup_push和pthread_cleanup_pop可以自动释放线程资源

      2、清理函数的执行时机:调用pthread_exit时;响应取消线程请求时;以非0参数调用pthread_cleanup_pop时

    代码test7_5.c

     1 //This is c program code!                                                                                                                      
     2 /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
     3   * 文档信息: *** :~/test7_5.c
     4   * 版权声明: *** :(魎魍魅魑)MIT
     5   * 联络信箱: *** :guochaoxxl@163.com
     6   * 创建时间: *** :2020年11月17日的下午08:02
     7   * 文档用途: *** :数据结构与算法分析-c语言描述
     8   * 作者信息: *** :guochaoxxl(http://cnblogs.com/guochaoxxl)
     9   * 修订时间: *** :2020年第46周 11月17日 星期二 下午08:02 (第322天)
    10   * 文件描述: *** :自行添加
    11  * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/
    12 #include <stdio.h>
    13 #include <pthread.h>
    14     
    15 #define MAXTHREADS 3
    16 
    17 void *myClear(void *iData){
    18     printf("clear: %c
    ", *((char *)iData));
    19 }   
    20 
    21 void *myComprint(void *iData){
    22     int oldState;
    23     int oldType;
    24     
    25     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldState);
    26     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldType);
    27     int *data = (int *)(iData);
    28     pthread_cleanup_push(myClear, "0");
    29     for(int i = 1; i < *data; i++){
    30         if((i % 250) == 0){
    31             printf("%d printf: %d
    ", *data, i);
    32             pthread_testcancel();
    33         }
    34     }
    35     pthread_cleanup_pop(1);
    36 }
    37 
    38 void *myComadd(void *iData){
    39     int oldState;
    40     int oldType;
    41 
    42     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldState);
    43     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldType);
    44 
    45     int sum = 0;
    46     int *data = (int *)(iData);
    47 
    48     for(int i = 0; i <= *data; i++){
    49         sum += i;
    50         printf("%d add %d
    ", i, sum);
    51     }
    52 }
    53 
    54 void *myCommul(void *iData){
    55     int oldState;
    56     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldState);
    57     int sum = 1;
    58     int *data = (int *)(iData);
    59 
    60     for(int i = 1; i <= *data; i++){
    61         sum *= i;
    62         printf("%d mul %d
    ", i, sum);
    63     }
    64 }
    65 
    66 int main(int argc, char **argv)
    67 {
    68     pthread_t threads[MAXTHREADS];                                                                                                             
    69     void *status;
    70     int n1 = 25;
    71     int n2 = 10000;
    72 
    73     pthread_create(&(threads[0]), NULL, myComprint, &n2);
    74     pthread_create(&(threads[1]), NULL, myComadd, &n1);
    75     pthread_create(&(threads[2]), NULL, myCommul, &n2);
    76
    77     for(int i = 0; i < MAXTHREADS; i++){
    78         pthread_cancel(threads[i]);
    79     }
    80     for(int i = 0; i < MAXTHREADS; i++){
    81         pthread_join(threads[i], &status);
    82         if(status == PTHREAD_CANCELED){
    83             printf("thread %d 已经取消!
    ", i);
    84         }else{
    85             printf("thread %d 不能被取消!
    ", i);
    86         }
    87     }
    88 
    89     return 0;
    90 }         
  • 相关阅读:
    centos7不能上网问题
    数据库修改为utf8mb4
    查看Linux系统信息
    如何查看Linux是否安装了gcc和gcc-c++
    nginx启动报错
    centos7无法上网问题
    notepad++如何将换行替换成其它符号?
    JAVA DESUtils加密工具
    Django之Model(一)--基础篇
    深刻理解Python中的元类(metaclass)以及元类实现单例模式
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/14002472.html
Copyright © 2020-2023  润新知