[英]g++ and gcc behave differently on pthread_cleanup_push/pop
This is my code这是我的代码
#include <pthread.h>
#include <stdio.h>
void cleanup(void *arg) {
printf("cleanup: %s\n", (const char*)arg);
}
void *thr_fn1(void *arg) {
printf("thread 1 strat\n");
pthread_cleanup_push(cleanup, (void*)"thread 1 first handler");
pthread_cleanup_push(cleanup, (void*)"thread 1 first handler");
if(arg)
return (void*)1;
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
return (void*)1;
}
void *thr_fn2(void *arg) {
printf("thread 2 strat\n");
pthread_cleanup_push(cleanup, (void*)"thread 2 first handler");
pthread_cleanup_push(cleanup, (void*)"thread 2 first handler");
if(arg)
return (void*)2;
pthread_cleanup_pop(0);
pthread_cleanup_pop(0);
return (void*)2;
}
int main() {
int err;
pthread_t tid1, tid2;
void *tret;
pthread_create(&tid1, NULL, thr_fn1, (void*)1);
pthread_create(&tid2, NULL, thr_fn2, (void*)1);
pthread_join(tid1, &tret);
printf("pthread 1 exit code %ld\n", tret);
pthread_join(tid2, &tret);
printf("pthread 2 exit code %ld\n", tret);
return 0;
}
Now I run it using gcc
and g++
现在我使用
gcc
和g++
运行它
$ gcc main.c -o main
$ ./main
thread 2 strat
thread 1 strat
pthread 1 exit code 1
pthread 2 exit code 2
$ g++ main.c -o main
$ ./main
thread 1 strat
cleanup: thread 1 first handler
cleanup: thread 1 first handler
thread 2 strat
cleanup: thread 2 first handler
cleanup: thread 2 first handler
pthread 1 exit code 1
pthread 2 exit code 2
$
gcc
and g++
are different.gcc
和g++
的实现是不同的。 So which one is a better implementation?On Linux, the
pthread_cleanup_push()
andpthread_cleanup_pop()
functions are implemented as macros that expand to text containing{
and}
, respectively.在 Linux 上,
pthread_cleanup_push()
和pthread_cleanup_pop()
函数实现为分别扩展为包含{
和}
的文本的宏。
# define pthread_cleanup_push(routine, arg) \
do { \
__pthread_cleanup_class __clframe (routine, arg)
If compiled with g++, __pthread_cleanup_class
is a C++ class:如果用
__pthread_cleanup_class
编译,__pthread_cleanup_class 是一个 C++ class:
#ifdef __cplusplus
/* Class to handle cancellation handler invocation. */
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); }
};
It behaves like any class, its destructor runs on scope end.它的行为与任何 class 一样,其析构函数在 scope 结束时运行。
In C, using gcc, cleanup handlers require pthread_exit()
, but your code does return
.在 C 中,使用 gcc,清理处理程序需要
pthread_exit()
,但您的代码确实return
了。
- When a thread terminates by calling
pthread_exit(3)
, all clean-up handlers are executed as described in the preceding point.当线程通过调用
pthread_exit(3)
终止时,所有清理处理程序都将按照前一点所述执行。 (Clean-up handlers are not called if the thread terminates by performing a return from the thread start function.)(如果线程通过从线程开始 function 执行返回而终止,则不会调用清理处理程序。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.