3

我有一个用 C 开发的程序。我在这个程序中添加了一个 sigaction 处理程序,以便在退出程序之前执行一些 C 代码:

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);
    }
    exit(EXIT_SUCCESS);
}

int main(int argc, char **argv)
{
    struct sigaction sigint_action;

    sigint_action.sa_handler = &signal_term_handler;
    sigemptyset(&sigint_action.sa_mask);

    sigint_action.sa_flags = SA_RESETHAND;
    sigaction(SIGTERM, &sigint_action, NULL);
        ...........
}

注意:我的程序包含 2 个正在运行的子线程

当我执行 myprogram 然后我打电话kill -15 <pidnumber>杀死我的程序。我在标准输出中收到"EXIT :TERM signal Received!\n“打印的消息,但程序没有退出。

我的 sigaction 代码中是否缺少某些内容?

4

3 回答 3

4

exit()不一定是异步信号安全的。

直接从信号处理程序调用_exit()或结束进程abort()


flock()并且函数系列的所有成员printf也不是异步信号保存。


有关异步信号安全功能的完整列表,您可能想单击此处

于 2013-06-06T15:51:17.050 回答
2

我仍然怀疑你有一个 XY 问题,即试图flock()在接收时取消文件SIGTERM

为了实现这一点(并以此绕过只能在信号接收上使用异步信号安全功能的限制,请使用以下方法:

  • 在主线程中屏蔽所有要由应用程序处理的信号。
  • 创建一个线程。
  • 通过修改线程的信号掩码,使该线程接收所有要处理的信号。
  • 在这个线程中循环sigwaitinfo()接收和发送信号。
  • 然后根据这个线程接收到的信号做需要做的事情,因为缺少任何功能的异步信号安全性而不受任何限制。
于 2013-06-07T08:33:00.313 回答
1

这很可能是因为实际上不允许您在信号处理程序中做很多事情(并且调用库函数肯定是粗略的)。

处理这样的事情的正常方法是让信号处理程序设置一个变量或排队一个正常主循环将处理然后退出的事件。

于 2013-06-06T15:47:42.753 回答