Mar*_*ity 1 c c++ gcc g++ pthreads
这是我的代码
#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;
}
Run Code Online (Sandbox Code Playgroud)
现在我使用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
$
Run Code Online (Sandbox Code Playgroud)
gcc我发现和的实现g++是不同的。那么哪一个是更好的实现呢?在 Linux 上,
pthread_cleanup_push()和pthread_cleanup_pop()函数被实现为宏,分别扩展为包含{和 的文本}。
# define pthread_cleanup_push(routine, arg) \
do { \
__pthread_cleanup_class __clframe (routine, arg)
Run Code Online (Sandbox Code Playgroud)
如果用g++编译,__pthread_cleanup_class是一个C++类:
#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); }
};
Run Code Online (Sandbox Code Playgroud)
它的行为就像任何类一样,它的析构函数在作用域末端运行。
在 C 中,使用 gcc,清理处理程序需要pthread_exit(),但您的代码需要return。
- 当线程通过调用终止时
pthread_exit(3),所有清理处理程序都会按照上一点所述执行。 (如果线程通过从线程启动函数执行返回而终止,则不会调用清理处理程序。)