相关函数
clean-up handlers:
void pthread_cleanup_push(void (*routine)(void *), void *arg);
void pthread_cleanup_pop(int execute);
void pthread_cleanup_handler(void *arg) { printf("pthread_cleanup_handler called.\n"); }
pthread_cleanup_push(pthread_cleanup_handler, NULL);
pthread_cleanup_pop(0);
例子:
调用pthread_exit函数终止线程时,clean-up handlers将全部弹出并被调用,调用顺序按照push顺序的反顺序。
如果有线程相关数据,在clean-up handlers调用后,对应的Thread-specific data destructors也将被调用,调用顺序未说明。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <errno.h> #include <sys/types.h> int *exitStatus = NULL; void pthread_cleanup_handler(void *arg) { printf("pthread_cleanup_handler called.\n"); } void* run_up(void *arg) { pid_t pid = getpid(); // pid_t tid = gettid(); // Glibc does not provide a wrapper for this system call; call it using syscall(2). pthread_t tid = pthread_self(); printf("pid: %ld, tid: %ld\n", pid, tid); printf("&exitStatus: %d, exitStatus: %d, *exitStatus: %d, &*exitStatus: %d\n", &exitStatus, exitStatus, *exitStatus, &*exitStatus); pthread_cleanup_push(pthread_cleanup_handler, NULL); pthread_exit((void *) exitStatus); pthread_cleanup_pop(0); return (void *) exitStatus; } int main() { exitStatus = (int *) malloc(sizeof(int)); *exitStatus = 8; pthread_t pthread1, pthread2; int result = pthread_create(&pthread1, NULL, run_up, (void *) 0); if (result) { printf("error: pthread_create, errno: %d\n", result); } printf("pthread: %ld\n", pthread1); int *p_status = (int *) malloc(sizeof(int)); int **status = &p_status; result = pthread_join(pthread1, (void **) status); if (result) { printf("error: pthread_join, errno: %d\n", result); } printf("&p_status: %d, p_status: %d, *p_status: %d, &*p_status: %d\n", &p_status, p_status, *p_status, &*p_status); printf("&status: %d, status: %d, *status: %d, &*status: %d, **status: %d, &**status: %d\n", &status, status, *status, &*status, **status, &**status); return 0; }
Thread-specific data destructors:
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));