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\n", *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\n", 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\n", 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 已经取消!\n", i);
74         }else{
75             printf("thread %d 不能被取消!\n", 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\n", *((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\n", *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\n", 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\n", 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 已经取消!\n", i);
84         }else{
85             printf("thread %d 不能被取消!\n", i);
86         }
87     }
88 
89     return 0;
90 }         

 

posted @ 2020-11-18 22:00  叕叒双又  阅读(536)  评论(0编辑  收藏  举报