如何使functionasynchronous信号安全?

我有以下的sigaction处理函数

 void signal_term_handler(int sig) { printf("EXIT :TERM signal Received!\n"); int rc = flock(pid_file, LOCK_UN | LOCK_NB); if(rc) { char *piderr = "PID file unlock failed!"; fprintf(stderr, "%s\n", piderr); printf(piderr); } abort(); } 

有人告诉我说, flockprintf不是asynchronous信号安全的。 在这个列表中 ,我找不到一个替代asynchronous信号安全的函数。

并根据以上链接:

当一个信号中断一个不安全的函数,信号捕获函数调用一个不安全的函数时,行为是不确定的

有没有办法使flockasynchronous信号安全? 还是有另一种解决scheme,当我收到TERM信号时执行flock

您可以使用fcntl()作为flock()的替代方法。

flock()通常是异步信号安全的,因为它是一个系统调用。 它的语义使它很难以不同的方式来实现。 它不在POSIX的异步信号安全函数列表中,因为它根本不在POSIX中。

您可能不需要显式解锁,因为当涉及打开文件描述的所有文件描述符都关闭时, flock()锁将自动释放。

printf()fprintf()调用应该被适当的write()调用替换。 stdio函数不在异步信号安全函数列表中,通常强烈异步信号不安全。

abort()调用可能是最好的取代,将信号设置为默认行为并重新发送给自己; 这样,shell就知道你的程序因为信号而退出,并且可以在适当的时候中止命令序列。

您可以在信号处理程序中使用exit()而不是abort() ,然后使用atexit()将不安全的函数放在退出处理程序中。

更新:通常,你不应该在你的信号处理程序中放置任何可能的阻塞系统调用。 避免这种情况的一种方法是在信号处理程序中设置一个标志,然后在主循环的上下文中执行所需的功能。

 volatile int shutdown = 0; void signal_term_handler(int sig) { shutdown = 1; } void cleanup() { printf("EXIT :TERM signal Received!\n"); int rc = flock(pid_file, LOCK_UN | LOCK_NB); if(rc) { char *piderr = "PID file unlock failed!"; fprintf(stderr, "%s\n", piderr); printf(piderr); } } void *workerFunction(void *arg) { while (!shutdown) { ... do stuff ... } return NULL; } int main(int argc, char *argv[]) { //... pthread_create(...,workerFunction,...); pthread_join(...); cleanup(); return 0; }