c – 是否可以在线程中使用exit?
发布时间:2020-12-16 07:04:41 所属栏目:百科 来源:网络整理
导读:我把exit()放到一个线程中,但我的程序有时不会退出. 根据这个link,exit()不是异步信号安全的.我想知道在一个线程中使用exit()是否会导致未定义的行为. 解决方法 普通退出(例如,与_exit相反)需要执行所有通常的atexit清理,输出 – 刷新等工作.可以构造在某些
我把exit()放到一个线程中,但我的程序有时不会退出.
根据这个link,exit()不是异步信号安全的.我想知道在一个线程中使用exit()是否会导致未定义的行为. 解决方法
普通退出(例如,与_exit相反)需要执行所有通常的atexit清理,输出 – 刷新等工作.可以构造在某些情况下挂起的代码,但我不得不做一个“明显的问题”来展示它.如果库例程(例如,内部stdio fflush)试图在其他线程持有的退出线程中获取锁(例如,在stdio流上),即使没有自己的atexit也可能获得类似的挂起.既然你没有展示你的代码,我只是在猜测.
这是一个测试程序(有故意的,明显的问题),当被告知时,至少在FreeBSD上会挂起. (格式化棘手,因为剪切和粘贴保持标签,但后来我不得不编辑一些空格…) #include <pthread.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> pthread_mutex_t global_mtx; void die(int error,const char *fmt,...) { va_list ap; va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); if (error) fprintf(stderr,": %sn",strerror(error)); else putc('n',stderr); fflush(stderr); _exit(0); } enum behavior { NORMAL,EXIT_WO_HANG,EXIT_W_HANG }; struct behave { enum behavior how; pthread_mutex_t lock; pthread_cond_t cond; int th1_entered; int th2_entered; }; void hanger(void); void *th1_main(void *); void *th2_main(void *); #define WR(x) (void)write(1,x,sizeof(x) - 1) int main(int argc,char **argv) { int error; struct behave how; pthread_t th1,th2; error = pthread_mutex_init(&global_mtx,NULL); if (error) die(error,"pthread_mutex_init global_mtx"); error = pthread_mutex_init(&how.lock,"pthread_mutex_init how.lock"); error = pthread_cond_init(&how.cond,"pthread_cond_init how.cond"); how.how = NORMAL; how.th1_entered = 0; how.th2_entered = 0; if (argc > 1) { if (strcmp(argv[1],"exit") == 0) how.how = EXIT_WO_HANG; else if (strcmp(argv[1],"hang") == 0) how.how = EXIT_W_HANG; else if (strcmp(argv[1],"normal") != 0) die(0,"usage: example [normal|exit|hang]"); } atexit(hanger); error = pthread_create(&th1,NULL,th1_main,&how); if (error) die(error,"pthread_create th1"); error = pthread_create(&th2,th2_main,"pthread_create th2"); /* now wait for threads */ error = pthread_join(th1,NULL); error = pthread_join(th2,NULL); printf("joined,normal exitn"); return 0; } void *th1_main(void *arg) { struct behave *how = arg; WR("thread 1 startn"); (void) pthread_mutex_lock(&global_mtx); (void) pthread_mutex_lock(&how->lock); how->th1_entered = 1; pthread_cond_signal(&how->cond); while (how->th2_entered == 0) (void) pthread_cond_wait(&how->cond,&how->lock); WR("thread 1 sees thread 2 startedn"); (void) pthread_mutex_unlock(&how->lock); if (how->how == EXIT_W_HANG) WR("thread 1 not unlockingn"); else (void) pthread_mutex_unlock(&global_mtx); return NULL; } void *th2_main(void *arg) { struct behave *how = arg; WR("thread 2 startn"); (void) pthread_mutex_lock(&how->lock); how->th2_entered = 1; pthread_cond_signal(&how->cond); while (how->th1_entered == 0) (void) pthread_cond_wait(&how->cond,&how->lock); WR("thread 2 sees thread 1 startedn"); (void) pthread_mutex_unlock(&how->lock); if (how->how != NORMAL) { WR("thread 2 exit()n"); exit(1); } return NULL; } void hanger(void) { /* this is what will cause us to hang,in the one case */ WR("hanger startn"); pthread_mutex_lock(&global_mtx); WR("hanger got global mutexn"); pthread_mutex_unlock(&global_mtx); WR("hanger finishn"); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |