c - sigaction 处理程序不关闭进程

标签 c asynchronous signals

我有以下 sigaction 处理程序代码

void signal_term_handler(int sig)
{
    int rc = async_lockf(pid_file, F_UNLCK);
    if(rc) {
        char piderr[] = "PID file unlock failed!\n";
        write(STDOUT_FILENO, piderr, (sizeof(piderr))-1);
    }
    close(pid_file);
    char exitmsg[] = "EXIT Daemon:TERM signal Received!\n";
    write(STDOUT_FILENO, exitmsg, (sizeof(exitmsg))-1);
    _exit(EXIT_SUCCESS); //async-signal-save exit
}

上述函数中的所有函数调用都是一个async-signal-save。甚至 async_lockf() 也是一个异步信号保存:

/*
 * The code of async_lockf is copied from eglibc-2.11.3/io/lockf.c
 * The lockf.c is under the terms of the GNU Lesser General Public
 * Copyright (C) 1994,1996,1997,1998,2000,2003 Free Software Foundation, Inc.
 * This file is part of the GNU C Library.
*/

int async_lockf(int fd, int cmd)
{
    struct flock fl = {0};

    /* async_lockf is always relative to the current file position.  */
    fl.l_whence = SEEK_CUR;
    fl.l_start = 0;
    fl.l_len = 0;

    switch (cmd)
    {
        case F_TEST:
            /* Test the async_lock: return 0 if FD is unlocked or locked by this process;
             return -1, set errno to EACCES, if another process holds the lock.  */
            fl.l_type = F_RDLCK;
            if (fcntl (fd, F_GETLK, &fl) < 0)
                return -1;
            if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
                return 0;
            errno = EACCES;
            return -1;

        case F_ULOCK:
            fl.l_type = F_UNLCK;
            cmd = F_SETLK;
            break;
        case F_LOCK:
            fl.l_type = F_WRLCK;
            cmd = F_SETLK;
            break;
        case F_TLOCK:
            fl.l_type = F_WRLCK;
            cmd = F_SETLK;
            break;

        default:
            errno = EINVAL;
            return -1;
    }

    /* async_lockf() is a cancellation point but so is fcntl() if F_SETLKW is
     used.  Therefore we don't have to care about cancellation here,
     the fcntl() function will take care of it.  */
    return fcntl (fd, cmd, &fl);
}

如果我执行 kill -15 命令,sigaction 处理程序应该关闭应用程序,但有时我让进程运行但不退出。这种情况很少发生。例如,如果我启动应用程序然后使用 kill -15 停止 1000 次,这种行为只会发生 ~5 次

对这种奇怪的行为有什么解释吗?为什么我的申请不存在?特别是我正在使用异步信号保存函数 (_exit()) 来关闭进程

最佳答案

要查看发生了什么,请尝试将 stracegdb 附加到进程并查看卡在何处。我的最佳猜测是您在执行阻塞操作时使用了屏蔽信号 (sigprocmask) 的代码,从而阻止信号处理程序运行。

关于c - sigaction 处理程序不关闭进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17025730/

相关文章:

javascript - 代码继续执行而不等待

python - 如何在Airflow中的PythonOperator的python_callable中提供异步函数?

c++ - QML signal QT slot with QQuickView

c - 我在c中实现循环链​​表的情况是否太多了

c# - 如何使用默认覆盖处理异步和等待

c - 需要帮助纠正我的斐波那契序列代码

linux - 从 linux 信号处理程序初始化 c++11 函数静态变量是否安全?

swift - 线程 1 : signal SIGTERM (in swift) when changing hardware in IOS simulator

c++ - 高效的浮点比较(Cortex-A8)

c - 每个 cpu 架构的真正 ELF TLS ABI 要求是什么?