我有以下的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(); }
有人告诉我说, flock
和printf
不是asynchronous信号安全的。 在这个列表中 ,我找不到一个替代asynchronous信号安全的函数。
并根据以上链接:
当一个信号中断一个不安全的函数,信号捕获函数调用一个不安全的函数时,行为是不确定的
有没有办法使flock
asynchronous信号安全? 还是有另一种解决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; }