如何取消待处理的信号?

mk.*_*k.. 1 linux signals

如何取消发送的信号到仍未送达的进程?

考虑我已向流程发送信号的情况,但该流程处于不可中断状态.

我正在有条件地等待处理信号.但由于它不是我想继续执行.在那种情况下,有没有办法可以取消发送的信号(尚未发送)

Fil*_*ves 8

如果在传送信号之前忽略该信号,则取消待处理信号.你只需要忽略这个信号.你可以做到这一点sigaction()通过设置sa_handler现场struct sigactionSIG_IGN.

这是一些示例代码,用于说明这一点,并说明它有效.代码执行以下操作:

  1. 阻塞SIGINT以便我们有一个时间窗口在SIGINT阻塞时发送它- 这将生成一个待处理的SIGINT,当过程信号掩码更改为不包含的掩码时将传递SIGINT(如果忽略该信号将被取消) ).
  2. 等你发送 SIGINT
  3. SIGINT知道a SIGINT待处理后忽略.这具有取消未决信号的效果.
  4. 恢复原始默认操作SIGINT,即终止进程
  5. 恢复原始过程信号掩码,不会阻塞SIGINT.
  6. 等待您输入要终止的任何字符.

您可以看到该过程在步骤5之后没有终止并等待您的输入,这意味着挂起的信号已被取消.

这是代码,说明了这一点:

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {

    sigset_t block_sigint, prev_mask;
    sigemptyset(&block_sigint);
    sigaddset(&block_sigint, SIGINT);

    if (sigprocmask(SIG_SETMASK, &block_sigint, &prev_mask) < 0) {
        perror("Couldn't block SIGINT");
        return 0;
    }

    printf("SIGINT blocked: kill -SIGINT %ld to generate a pending SIGINT. Press return when done.\n", (long) getpid());

    /* Now, open a new terminal and send SIGINT to this process.
     *
     * After doing that, the signal will be pending delivery because it is currently blocked.
     *
     * Now, if we ignore SIGINT, the pending signal will be cancelled
     */

    getchar();

    struct sigaction ign_sigint, prev;
    ign_sigint.sa_handler = SIG_IGN;
    ign_sigint.sa_flags = 0;
    sigemptyset(&ign_sigint.sa_mask);

    if (sigaction(SIGINT, &ign_sigint, &prev) < 0) {
        perror("Couldn't ignore SIGINT");
        return 0;
    }

    printf("SIGINT ignored - pending SIGINT was canceled.\n");

    /* Now, restore the default action for SIGINT */
    if (sigaction(SIGINT, &prev, NULL) < 0) {
        perror("Couldn't restore default SIGINT behavior");
        return 0;
    }

    /* And also restore the process's original sigmask, which does not block SIGINT */
    if (sigprocmask(SIG_SETMASK, &prev_mask, NULL) < 0) {
        perror("Couldn't restore original process sigmask");
        return 0;
    }

    printf("Process sigmask and action for SIGINT are now restored\n");

    /* We will not receive SIGINT at this point because it was canceled
     * So the process will block on getchar() here instead of terminating
     */
    getchar();

    return 0;   
}
Run Code Online (Sandbox Code Playgroud)