1、
pthread_cleanup_push和pthread_cleanup_pop是成对出现的,这两个函数实际是宏定义,不成对出现根本编译不过( '{' '}' 不配对)
2、
由pthread_cancel引起的线程结束,会次序执行由pthread_cleanup_push压入的函数
3、
由pthread_exit引起的线程结束,会次序执行由pthread_cleanup_push压入的函数
4、
如在pthread_cleanup_push和pthread_cleanup_pop之间用return结束线程,则pthread_cleanup_push压入的函数不被执行
5、
当线程运行到pthread_cleanup_pop(int execute),压入的函数是否执行,由pthread_cleanup_pop(int execute)的execute参数决定
These functions manipulate the calling thread's stack of thread-cancellation clean-up handlers. A clean-up handler is a function that is automatically executed when a thread is
canceled (or in various other circumstances described below); it might, for example, unlock a mutex so that it becomes available to other threads in the process.
The pthread_cleanup_push() function pushes routine onto the top of the stack of clean-up handlers. When routine is later invoked, it will be given arg as its argument.
The pthread_cleanup_pop() function removes the routine at the top of the stack of clean-up handlers, and optionally executes it if execute is nonzero.
A cancellation clean-up handler is popped from the stack and executed in the following circumstances:
1. When a thread is canceled, all of the stacked clean-up handlers are popped and executed in the reverse of the order in which they were pushed onto the stack.
2. When a thread terminates by calling pthread_exit(3), all clean-up handlers are executed as described in the preceding point. (Clean-up handlers are not called if the thread
terminates by performing a return from the thread start function.)
3. When a thread calls pthread_cleanup_pop() with a nonzero execute argument, the top-most clean-up handler is popped and executed.
POSIX.1 permits pthread_cleanup_push() and pthread_cleanup_pop() to be implemented as macros that expand to text containing '{' and '}', respectively. For this reason, the
caller must ensure that calls to these functions are paired within the same function, and at the same lexical nesting level. (In other words, a clean-up handler is only estab-
lished during the execution of a specified section of code.)
Calling longjmp(3) (siglongjmp(3)) produces undefined results if any call has been made to pthread_cleanup_push() or pthread_cleanup_pop() without the matching call of the pair
since the jump buffer was filled by setjmp(3) (sigsetjmp(3)). Likewise, calling longjmp(3) (siglongjmp(3)) from inside a clean-up handler produces undefined results unless the
jump buffer was also filled by setjmp(3) (sigsetjmp(3)) inside the handler.
混乱的测试代码
static void* Test(void *p)
{
pthread_cleanup_push(cleanup,p);
printf("Test sleep(10) before\n");
sleep(1);
printf("Test sleep(10) after\n");
pthread_cleanup_pop(0);
}
int RemoteCtrlServiceOpen(int wait)
{
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
char *arg = (char*)malloc(246);
printf("pthread_create before %p\n", arg);
pthread_create(&tid, &attr, Test, arg);
printf("pthread_create after %p\n", arg);
printf("pthread_cancel sleep 5 before\n");
sleep(5);
pthread_cancel(tid);
printf("pthread_cancel sleep 5 after\n");
sleep(600);
return Start(wait);
}