- 论坛徽章:
- 0
|
回复 7# iw1210
这不是我的说法,是 man 的说法。
//////////////////////////
编程不是自然科学,研究的领域不是未知的,不需要自己猜测或者探索某个函数的运行规律。看手册就全知道了。
究竟弹没弹、什么时候弹、什么时候不弹,直接在命令行里敲 man pthread_cleanup_pop 就全知道了,你问别人,别人也是从那里拿来的信息。
//////////////////////////
但编程是科学,究竟行不行、是不是,自己实验一下就知道了。
最不济,打开 /usr/include/pthread.h 看看:- # define pthread_cleanup_push(routine, arg) \
- do { \
- __pthread_cleanup_class __clframe(routine, arg)
- # define pthread_cleanup_pop(execute) \
- __clframe.__setdoit(execute); \
- } while (0)
复制代码 宏定义展开总会吧?- pthread_cleanup_push(cleanup, NULL);
- ...
- pthread_cleanup_pop(0);
复制代码 变成:- do {
- __pthread_cleanup_class __clframe(routine, arg);
- ...
- __clframe.__setdoit(execute);
- } while(0);
复制代码 可见一次调用实质上只增加了一个 __clframe 这个对象,而这个对象是在栈上的。那么你担心的「直接中断退出会不会造成资源泄漏」也只可能是因为 __pthread_cleanup_class 类内部有资源没有释放吧。
那么我们再看上面的 __pthread_cleanup_class 类:- class __pthread_cleanup_class
- {
- void (*__cancel_routine) (void *);
- void *__cancel_arg;
- int __do_it;
- int __cancel_type;
- public:
- __pthread_cleanup_class (void (*__fct) (void *), void *__arg)
- : __cancel_routine (__fct), __cancel_arg (__arg), __do_it (1) { }
- ~__pthread_cleanup_class () { if (__do_it) __cancel_routine (__cancel_arg); }
- void __setdoit (int __newval) { __do_it = __newval; }
- void __defer () { pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED,
- &__cancel_type); }
- void __restore () const { pthread_setcanceltype (__cancel_type, 0); }
- };
复制代码 究竟可不可能泄漏、什么情况下可能泄漏就很明显了。
当然看具体实现只是没办法的办法,实现不一定遵循标准。所以还是看 man 来得划算。 |
|