gpt4 book ai didi

linux - 如何取消挂起的信号?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:17:55 25 4
gpt4 key购买 nike

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

考虑我向进程发送信号但进程处于不可中断状态的场景。

我正在有条件地等待信号被处理。但既然没有,我想继续执行下去。在那种情况下,有没有一种方法可以取消发送的信号(尚未发送)

最佳答案

如果信号在传递之前被忽略,则挂起信号将被取消。你只需要忽略信号。您可以通过将 struct sigaction 中的 sa_handler 字段设置为 SIG_IGN 来使用 sigaction() 执行此操作。

这里有一些示例代码可以说明这一点并表明它可以正常工作。该代码执行以下操作:

  1. 阻止 SIGINT 以便我们有一个时间窗口在它被阻止时发送它 SIGINT - 这将生成一个待处理的 SIGINT当进程信号掩码更改为不包含 SIGINT 的掩码时将被传送(如果信号被忽略将被取消)。
  2. 等待您发送SIGINT
  3. 在知道 SIGINT 未决后忽略 SIGINT。这具有取消挂起信号的效果。
  4. 恢复SIGINT原来的默认 Action ,即终止进程
  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;
}

关于linux - 如何取消挂起的信号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30706796/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com