gpt4 book ai didi

c - 为什么忽略 SIGCONT 仍会使进程继续?

转载 作者:行者123 更新时间:2023-12-01 22:46:54 26 4
gpt4 key购买 nike

这是我的代码,忽略SIGCONT:

int main() {
signal(SIGCONT, SIG_IGN);
while(1);
}

是这样的:

> ./main &
[1] 25093
> kill -STOP 25093

[1]+ Stopped ./main
> ps -aux | grep 25093
xxx 25093 98.6 0.0 2488 872 pts/8 T 18:23 0:20 ./main
> kill -CONT 25093
> ps -aux | grep 25093
xxx 25093 52.1 0.0 2488 872 pts/8 R 18:23 0:28 ./main
  1. 看来 SIGCONT 仍然让我的进程继续。这是否意味着 SIGCONT 的处理程序只是一个“副作用”?

  2. 我想知道什么时候 SIGCONT 使进程再次运行?什么时候进程又被放入dispatch queue?是在执行 kill 系统调用时还是在调度进程时? (我读了一篇关于 Linux 信号的文章,指出调度代码没有特别对待 SIGCONT。代码段如下所示。)

if (ka->sa.sa_handler == SIG_DFL) { 
int exit_code = signr;

/* Init gets no signals it doesn't want. */
if (current->pid == 1)
continue;

switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
continue;

case SIGTSTP: case SIGTTIN: case SIGTTOU:
if (is_orphaned_pgrp(current->pgrp))
continue;
/* FALLTHRU */

case SIGSTOP:
current->state = TASK_STOPPED;
current->exit_code = signr;
if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
continue;

case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */

default:
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* NOTREACHED */
}
}
...
handle_signal(signr, ka, &info, oldset, regs);
return 1;
}
...
return 0;

最佳答案

根据 POSIX 标准,这是 SIGCONT 的预期行为。引自 POSIX.1-2017 chapter 2 ,第 2.4 节“信号概念”,第 2.4.1 小节:

When SIGCONT is generated for a process that is stopped, the process shall be continued, even if the SIGCONT signal is ignored by the process or is blocked by all threads within the process and there are no threads in a call to a sigwait() function selecting SIGCONT. If SIGCONT is blocked by all threads within the process, there are no threads in a call to a sigwait() function selecting SIGCONT, and SIGCONT is not ignored by the process, the SIGCONT signal shall remain pending on the process until it is either unblocked by a thread or a thread calls a sigwait() function selecting SIGCONT, or a stop signal is generated for the process or any of the threads within the process.

您不能阻止 SIGCONT 恢复执行您的进程。您最多能做的就是阻止它的传递,这意味着如果您将 SIGCONT 添加到被阻止的信号集中,您的进程将不会“注意到”它(已注册的处理程序在解除阻止之前不会运行),但它会尽管如此恢复执行。


在 Linux 中,SIGCONT 的“继续”操作在信号生成时立即执行,即在 kill 系统调用期间。这是在检查信号是否被阻止或忽略之前完成的。负责此的代码在 prepare_signal() 中。 :

/*
* Handle magic process-wide effects of stop/continue signals. Unlike
* the signal actions, these happen immediately at signal-generation
* time regardless of blocking, ignoring, or handling. This does the
* actual continuing for SIGCONT, but not the actual stopping for stop
* signals. The process stop is done as a signal action for SIG_DFL.
*
* Returns true if the signal should be actually delivered, otherwise
* it should be dropped.
*/
static bool prepare_signal(int sig, struct task_struct *p, bool force)
{
// ...

} else if (sig == SIGCONT) {
unsigned int why;
/*
* Remove all stop signals from all queues, wake all threads.
*/
siginitset(&flush, SIG_KERNEL_STOP_MASK);
flush_sigqueue_mask(&flush, &signal->shared_pending);
for_each_thread(p, t) {
flush_sigqueue_mask(&flush, &t->pending);
task_clear_jobctl_pending(t, JOBCTL_STOP_PENDING);
if (likely(!(t->ptrace & PT_SEIZED))) {
t->jobctl &= ~JOBCTL_STOPPED;
wake_up_state(t, __TASK_STOPPED);
} else
ptrace_trap_notify(t);
}

// ...
}

关于c - 为什么忽略 SIGCONT 仍会使进程继续?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75081680/

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