#include #include #include #include #include int global_data; void clean(void *data) // 清理函数的耗时属于调用线程 { printf("开始清理数据: %p\n", data); global_data = *((int *)data); free(data); } void *task(void *data) { int n = atoi((char *)data); int *total = malloc(4); pthread_cleanup_push(clean, total); for (int i = 1; i <= n; i++) { *total += i; usleep(200 * 1000); } pthread_cleanup_pop(1); pthread_exit(NULL); // 加入清理函数后,但数据的退出无意义 } typedef struct delay_cancel_info { pthread_t tid; int delay; } DELAY_INFO; void *delay_cancel(void *data) { DELAY_INFO *info = (DELAY_INFO *)data; sleep(info->delay); printf("%ld 线程即将取消\n", info->tid); pthread_cancel(info->tid); } int main(int argc, char const *argv[]) { if (argc != 3) { printf("usage: %s number delay_time\n", argv[0]); return 0; } pthread_t tid; pthread_create(&tid, NULL, task, (void *)argv[1]); DELAY_INFO info = {tid, atoi(argv[2])}; pthread_t tid2; pthread_create(&tid2, NULL, delay_cancel, &info); if (pthread_join(tid, NULL) == 0) { printf("%ld 子线程返回数据: %d\n", tid, global_data); } return 0; } /* 【小结】在线程加入的清理函数时,原线程中的pthread_exit()则不能正常返回数据。因此,在清理函数内,将当前堆的数据赋值给全局变量,在主线程中进行使用。 */