这是我的代码,忽略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
的句柄只是一个“副作用”?
1.不知道SIGCONT
什么时候让进程重新运行,什么时候又把进程放到调度队列中,是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(¤t->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;
1条答案
按热度按时间ahy6op9u1#
根据POSIX标准,这是
SIGCONT
的预期行为。引自POSIX.1-2017 chapter 2,第2.4节“信号概念”,第2.4.1小节:**当为停止的进程生成
SIGCONT
时,即使SIGCONT
信号被进程忽略或被进程内的所有线程阻塞,并且在对sigwait()
函数的调用中没有线程选择SIGCONT
,进程也应继续。**如果SIGCONT
被进程内的所有线程阻塞,在对选择SIGCONT
的sigwait()
函数的调用中没有线程,并且SIGCONT
未被进程忽略,则SIGCONT
信号将在进程上保持未决直到其被线程解除阻塞或者线程调用选择SIGCONT
的sigwait()
函数,或者为进程或进程内的任何线程生成停止信号。你不能阻止
SIGCONT
继续执行你的进程,你最多只能阻止它的传递,这意味着如果你把SIGCONT
添加到被阻止的信号集合中,你的进程将不会“注意到”它(注册的处理程序将不会运行,直到解除阻止),但它仍然会继续执行。在Linux中,
SIGCONT
的“continuing”操作在信号生成时立即执行,即在kill
系统调用期间。这甚至在检查信号是否被阻塞或忽略之前就已完成。负责此操作的代码位于prepare_signal()
中: