我有以下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
不是异步信号安全的。我在list中找不到flock
的备用异步信号安全功能。
并根据以上链接:
当信号中断不安全功能和信号捕获时 函数调用不安全的函数,行为未定义
有没有办法让flock
异步信号安全?或者,当我收到flock
信号时,是否有其他解决方案来执行TERM
答案 0 :(得分:4)
您可以使用fcntl()替代flock()。
答案 1 :(得分:4)
flock()
通常是异步信号安全的,因为它是一个系统调用。它的语义使得以不同方式实现它变得困难。它不在POSIX的异步信号安全函数列表中,因为它根本不在POSIX中。
您可能不需要显式解锁,因为当引用打开的文件描述的所有文件描述符都关闭时会自动释放flock()
锁。
printf()
和fprintf()
来电应替换为适当的write()
来电。 stdio函数不在异步信号安全函数列表中,并且通常强烈异步信号不安全。
最好将abort()
调用替换为将信号设置为默认操作并将其重新发送为self;这样,shell知道您的程序因信号而退出,并且可以在适当的时候中止命令序列。
答案 2 :(得分:0)
您可以在信号处理程序中使用 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;
}