当我研究一些关于使用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的内容是不可重入的......但是在信号处理程序中使用它仍然是一个问题,即使它会导致程序的退出? 谢谢,如果这是一个愚蠢的问题,任何帮助都表示赞赏和抱歉。
答案 0 :(得分:3)
您可以在信号处理程序中安全地执行的唯一操作是设置volatile sig_atomic_t变量。请通过检查已接收到信号(在信号处理程序之外),在程序的主循环中执行所有处理。如果你必须开始做非便携式的东西,那么至少考虑使用_Exit()或_exit()。某些C库将保证某些功能是信号安全的,但不能保证在不同的系统上工作。
答案 1 :(得分:0)
取决于“...... DO STUFF ......”可能会出现问题。如果在那里完成的东西可能没有完成两次(比如释放相同的指针),它可能会崩溃。
在您的特定情况下,如果close(fileFD)是影响全局状态的唯一事物,并且您的文件访问API允许双重关闭文件,则这可能不会成为问题。
答案 2 :(得分:0)
如果您使用任何异步不安全的功能,仍然不安全。像USR1
这样的异步信号可能出现在程序中的任何两条指令之间,包括在某些库代码的关键部分(锁定部分)的中间。
因此,例如,如果中断发生在malloc
的中间,则在信号处理程序中调用free
(例如清理)将会死锁。