1

当我研究了一些关于用 C 进行 unix 编程的知识时,我了解到在信号处理程序中应该避免无法重入的函数,但是如果我有类似的东西:

int main(int argc, char** argv){
     ...
    fileFd=open(...) 
    signal(SIGUSR1, signalHandler)
    ...
}


void signalHandler(int signo){
    switch(signo){

    case SIGUSR1:
        myExit(EXIT_FAILURE);   
        break;

    default: 
        break;

    }
}

myExit 在哪里

void myExit(int ret){

    ...DO STUFF...
    close(fileFd);
    exit(ret);

}

并且 fileFd 是一个全局变量,如果我没记错的话,这使得 myExit 成为不可重入的......但在信号处理程序中使用它仍然是一个问题,即使它会导致程序退出?谢谢,如果这是一个愚蠢的问题,任何帮助表示赞赏和抱歉。

4

3 回答 3

4

您可以在信号处理程序中安全地做的唯一一件事就是设置一个 volatile sig_atomic_t 变量。请通过检查是否已收到信号(在信号处理程序之外)在程序的主循环中进行所有处理。如果你必须开始做一些非便携的事情,那么至少考虑使用 _Exit() 或 _exit()。某些 C 库将保证某些函数是信号安全的,但这显然不能保证在不同的系统上工作。

于 2012-09-10T19:11:39.877 回答
0

根据“...DO STUFF...”,它可能会出现问题。如果在那里完成的事情可能没有完成两次(比如释放同一个指针),它可能会崩溃。

但是,在您的特定情况下,如果 close(fileFD) 是影响全局状态的唯一因素并且您的文件访问 API 允许双重关闭文件,这可能不会成为问题。

于 2012-09-10T19:12:07.033 回答
0

如果您使用任何异步不安全的功能,仍然不安全。像这样的异步信号USR1可以发生在程序中的任意两条指令之间,包括在某些库代码中的关键部分(锁定部分)的中间。

因此,例如,如果中断发生在 中间malloc,则调用free信号处理程序(例如清理)将死锁。

于 2012-09-10T19:12:07.953 回答