递归请求的信号会发生什么情况?

递归请求的信号会发生什么情况?

如果流程变得缓慢,人们经常会取消Ctrl + cCtrl + z放弃工作,在这种情况下,这些信号中的哪一个被处理,第一的一个或最后的一?是每个信号处理?如果不是,那么哪些是被忽略

答案1

如果接收者在下一个信号到来之前有时间开始处理信号,那么所有信号将按顺序处理。

当进程接收到信号但尚未准备好处理它时(例如信号被屏蔽或进程停止),内核将信号标记为待处理。信号将被传递。

如果在进程未准备好时接收到多个不同编号的信号,则将处理所有信号。信号被一一传递给进程。它们的交付顺序是POSIX 未指定;在Linux,它们按编号传递,最小的在前(例如,如果待处理,SIGHUP=1 将首先传递,然后是 SIGQUIT=2,等等);自由BSD不作任何保证。

如果在进程未准备好时接收到具有相同编号的多个信号,则这些信号可能会被合并。 POSIX 没有指定会发生什么,但大多数 unice 都会合并。例如,如果您运行kill -1 234; kill -1 234,那么进程 234 的信号 1 处理程序是否被接收一次或两次是一个时间问题,这取决于 234 是否获得了传递第一个信号的时间片。

答案2

信号按照您通过终端键入信号的顺序发送到内核。如果使用Ctrl+,C则指示内核将信号 SIGINT 发送到前台进程组。收到此消息后,正在运行的命令将被终止。

使用Ctrl+表示Z您正在发送信号 SIGSTP。这实际上并没有终止该进程,只是告诉它暂时停止。使用此功能时,您可以通过命令告诉 shell 将其带回到前台来恢复进程,fg或者您可以使用命令将其置于后台bg

如果作业已通过 SIGSTP 信号停止,那么您可以使用kill如下命令真正终止它:

$ kill %1

%1您刚刚 SIGSTP 的作业的作业 ID 在哪里。

检查已停止的作业

您可以使用以下job命令查看 shell 中哪些作业已停止,如下所示:

$ sleep 1000 
^Z
[1]+  Stopped                 sleep 1000
$ jobs
[1]+  Stopped                 sleep 1000

在这里我使用Ctrl+Z来停止我的sleep 1000命令。在输出中,[1]对应于%1我上面提到的。像这样杀死它会产生与Ctrl+相同的效果C

$ kill %1
[1]+  Terminated              sleep 1000

fg我上面提到的and命令将作用于编号后面bg带有加号的作业。+注意这里的jobs输出:

[1]+  Stopped                 sleep 1000

如果我有几份工作,那就更明显了,例如:

$ jobs
[1]   Stopped                 sleep 1000
[2]-  Stopped                 sleep 2000
[3]+  Stopped                 sleep 3000

因此,任何裸露命令fgbg命令都将与+.我可以像这样定位一个特定的目标:

$ fg %1
sleep 1000

相关内容