APUE2勘误-11.5节 线程终止(关于线程清理处理程序)

本文探讨了Linux环境下线程清理函数的触发条件及其执行差异。针对不同Linux内核版本(如2.4.22与2.6.28),讨论了线程执行return与pthread_exit时清理函数的行为变化。

平台:Linux 2.6.28-19-generic

书中讲解所用的linux版本为Linux 2.4.22,我没有在此版本上做实验的机会,只是在当前用的版本上做了测试,问题原因可能是Linux内核版本升级导致对线程终止的处理方式进行了改动。

代码如下:

 1 #include "apue.h"
2 #include <pthread.h>
3
4 void
5 cleanup(void *arg)
6 {
7 printf("cleanup: %s\n", (char *)arg);
8 }
9
10 void *
11 thr_fn1(void *arg)
12 {
13 printf("thread 1 start\n");
14 pthread_cleanup_push(cleanup, (void*)"thread 1 first handler");
15 pthread_cleanup_push(cleanup, (void*)"thread 1 second handler");
16 printf("thread 1 push complete\n");
17 if (arg)
18 return((void *)1);
19 pthread_cleanup_pop(0);
20 pthread_cleanup_pop(0);
21 return((void *)1);
22 }
23
24 void *
25 thr_fn2(void *arg)
26 {
27 printf("thread 2 start\n");
28 pthread_cleanup_push(cleanup, (void*)"thread 2 first handler");
29 pthread_cleanup_push(cleanup, (void*)"thread 2 second handler");
30 printf("thread 2 push complete\n");
31 if (arg)
32 pthread_exit((void *)2);
33 pthread_cleanup_pop(0);
34 pthread_cleanup_pop(0);
35 pthread_exit((void *)2);
36 }
37
38 int
39 main(void)
40 {
41 int err;
42 pthread_t tid1, tid2;
43 void *tret;
44
45 err = pthread_create(&tid1, NULL, thr_fn1, (void *)1);
46 if (err != 0)
47 err_quit("can't create thread 1: %s\n", strerror(err));
48 err = pthread_create(&tid2, NULL, thr_fn2, (void *)1);
49 if (err != 0)
50 err_quit("can't create thread 2: %s\n", strerror(err));
51 err = pthread_join(tid1, &tret);
52 if (err != 0)
53 err_quit("can't join with thread 1: %s\n", strerror(err));
54 printf("thread 1 exit code %d\n", (int)tret);
55 err = pthread_join(tid2, &tret);
56 if (err != 0)
57 err_quit("can't join with thread 2: %s\n", strerror(err));
58 printf("thread 2 exit code %d\n", (int)tret);
59 exit(0);
60 }

程序运行结果:

 1 thread 1 start
2 thread 1 push complete
3 cleanup: thread 1 second handler
4 cleanup: thread 1 first handler
5 thread 2 start
6 thread 2 push complete
7 cleanup: thread 2 second handler
8 cleanup: thread 2 first handler
9 thread 1 exit code 1
10 thread 2 exit code 2

在原书中提到,

当线程执行以下动作时调用清理函数,

1.调用pthread_exit时;

2.响应取消请求时;

3.用非零execute函数调用pthread_cleanup_pop时。

注意,并不包括线程执行return函数,对应的在原书中给出的编程结果,没有程序运行结果中给出的第3、4行,也即线程1的线程清理函数是没有被执行的。但实际运行情况是,在Linux 2.6版本中,线程执行函数通过return返回,也会执行线程清理。

因此,需要对线程清理函数的触发条件,以及对应的执行结果作相应的update。

现在还有一个疑问:

线程执行环境中调用return返回和调用pthread_exit返回有什么区别吗?(return本身也要求将返回值显示转换成void*)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值