pthread_cleanup_push(3) Library Functions Manual pthread_cleanup_push(3) pthread_cleanup_push, pthread_cleanup_pop - POSIX (libpthread -lpthread) #include void pthread_cleanup_push(typeof(void (void *)) *routine, void *arg); void pthread_cleanup_pop(int execute); . ( ) (mutex) . pthread_cleanup_push() routine . routine arg . pthread_cleanup_pop() execute . : o . o pthread_exit(3) . ( return .) o pthread_cleanup_pop() execute . POSIX.1 pthread_cleanup_push() pthread_cleanup_pop() '{' '}' . . ( .) longjmp(3) (siglongjmp(3)) pthread_cleanup_push() pthread_cleanup_pop() setjmp(3) (sigsetjmp(3)). longjmp(3) (siglongjmp(3)) setjmp(3) (sigsetjmp(3)) . . . attributes(7). +------------+------------------------------------+--------------------+ || | | +------------+------------------------------------+--------------------+ |pthread_cleanup_push(),| | MT-Safe | |pthread_cleanup_pop()| | | +------------+------------------------------------+--------------------+ glibc pthread_cleanup_push() pthread_cleanup_pop() '{' '}' . . POSIX.1 return break continue goto pthread_cleanup_push() pthread_cleanup_pop() . . POSIX.1-2008. POSIX.1-2001. glibc 2.0. . pthread_cleanup_push() pthread_cleanup_pop(). cnt . ( return). : $ ./a.out; New thread started cnt = 0 cnt = 1 Canceling thread Called clean-up handler Thread was canceled; cnt = 0 cnt 0. : $ ./a.out x; New thread started cnt = 0 cnt = 1 Thread terminated normally; cnt = 2 ( cleanup_pop_arg 0) cnt. cleanup_pop_arg: $ ./a.out x 1; New thread started cnt = 0 cnt = 1 Called clean-up handler Thread terminated normally; cnt = 0 pthread_cleanup_pop() . #include #include #include #include #include #include #include static int done = 0; static int cleanup_pop_arg = 0; static int cnt = 0; static void cleanup_handler(void *arg) { printf("Called clean-up handler\n"); cnt = 0; } static void * thread_start(void *arg) { time_t curr; printf("New thread started\n"); pthread_cleanup_push(cleanup_handler, NULL); curr = time(NULL); while (!done) { pthread_testcancel(); /* A cancelation point */ if (curr < time(NULL)) { curr = time(NULL); printf("cnt = %d\n", cnt); /* A cancelation point */ cnt++; } } pthread_cleanup_pop(cleanup_pop_arg); return NULL; } int main(int argc, char *argv[]) { pthread_t thr; int s; void *res; s = pthread_create(&thr, NULL, thread_start, NULL); if (s != 0) errc(EXIT_FAILURE, s, "pthread_create"); sleep(2); /* Allow new thread to run a while */ if (argc > 1) { if (argc > 2) cleanup_pop_arg = atoi(argv[2]); done = 1; } else { printf("Canceling thread\n"); s = pthread_cancel(thr); if (s != 0) errc(EXIT_FAILURE, s, "pthread_cancel"); } s = pthread_join(thr, &res); if (s != 0) errc(EXIT_FAILURE, s, "pthread_join"); if (res == PTHREAD_CANCELED) printf("Thread was canceled; cnt = %d\n", cnt); else printf("Thread terminated normally; cnt = %d\n", cnt); exit(EXIT_SUCCESS); } pthread_cancel(3) pthread_cleanup_push_defer_np(3) pthread_setcancelstate(3) pthread_testcancel(3) pthreads(7) 3 . . : . 6.18 20 2025 pthread_cleanup_push(3)