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");
}(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! | 
