如何以比平时更温和的方式结束所有具有相同名称的进程killall
?我不想中断这些过程,但给他们留出适当的时间退出。
也可以看看:
如何以比平时更温和的方式结束所有具有相同名称的进程killall
?我不想中断这些过程,但给他们留出适当的时间退出。
也可以看看:
Answers:
killall
默认情况下发送SIGTERM
。这已经是一种不错的方法,它使应用程序有机会自行清理。“现在已经死了!” 方法是发送SIGKILL
信号,这需要将其指定为的选项killall
。来自GNU C库:终止信号:
巨集:int SIGTERM
[...] 礼貌地要求程序终止是正常的方法。
您链接到有关GNOME系统监视器的问题。这也确实SIGTERM
适用于其“结束流程”操作(而且我意识到我与该问题的答案相矛盾)。您可以在源代码中找到它来验证自己:
<item>
<attribute name="label" translatable="yes">_End</attribute>
<attribute name="action">win.send-signal-end</attribute>
<attribute name="accel"><Primary>e</attribute>
<attribute name="target" type="i">15</attribute>
</item>
这里的15是信号编号。信号15为SIGTERM
。SIGTERM
在询问和回答其他问题之前,System Monitor已经使用了很长时间。
查看的Github表示形式git blame
,这是对GNOME System Monitor的源代码中的信号拼写方式进行的更改:
383007f2 2013年7月24日用GAction参数
0e766b2d替换了用于发送信号的重复代码2013年7月18日将端口进程弹出菜单转到GAction
97674c79 2012年10月3日摆脱了ProcData结构
38c5296c 2011年7月3日使缩进在源文件中统一。
这些都没有从更改SIGQUIT
为SIGTERM
,最后一个是在提出链接问题之前。
15
?它可能已在某些时候进行了更改,因此旧答案相对于旧版本可能是100%正确。
git grep 'SIGQUIT'
没有显示任何内容。均未发现与信号相关的任何东西git grep '>3<'
。我得出结论,最有可能的gnome-system-monitor从未使用过SIGQUIT
。
git grep
仅搜索当前树,而不搜索整个历史记录。我使用了git blame
(实际上是与Github相当的工具)来进行更深入的挖掘,但仍然没有任何结果。
@hvd的答案基本上是正确的。为了进一步备份该文件,init
进程将SIGTERM
在关闭计算机时首先发送到进程,然后在SIGKILL
尚未退出的情况下发送延迟。进程无法处理/忽略SIGKILL
。
不过,要给出更多细节,真正的答案是您无法确定程序会处理它。SIGTERM
是礼貌地要求程序退出的最常用信号,但是所有信号处理都取决于程序对信号的处理方式。
换句话说,根据其他答案,如果您有一个由@Jos或@AlexGreg编写的程序,则它们可能正在处理SIGQUIT
但可能没有处理SIGTERM
,因此发送的SIGTERM
“软性”不如SIGQUIT
。
我已经编写了一些代码,因此您可以自己使用它。将以下内容另存为signal-test.c
,然后使用
gcc -o signal-test signal-test.c
然后可以运行它./signal-test
,并查看当您使用发出不同的信号时会发生什么killall -s <signal>
。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int flag = 0;
void handle_signal(int s)
{
flag = s;
}
int main(int argc, char *argv[])
{
signal(SIGTERM, handle_signal);
signal(SIGQUIT, handle_signal);
while(flag == 0){
sleep(1);
}
printf("flag is %d\n", flag);
return flag;
}
就目前而言,该代码可以优雅地处理SIGTERM和SIGQUIT。您可以尝试注释掉各行signal(SIG...
(//
在行的开头使用a )以删除信号处理程序,然后运行并再次发送信号。您应该能够看到这些不同的输出:
$ ./signal-test
Terminated
$ ./signal-test
Quit (core dumped)
$ ./signal-test
flag is 15
$ ./signal-test
flag is 3
取决于您是否处理信号。
您也可以尝试忽略信号:
signal(SIGTERM, SIG_IGN);
如果这样做,那么发送SIGTERM
将无济于事,您将不得不使用它SIGKILL
来结束该过程。
中的更多详细信息man 7 signal
。请注意,signal()
以这种方式使用被认为是不可携带的-尽管比其他方式容易得多!
另一个较小的脚注-在Solaris上killall
试图杀死所有进程。他们全部。如果您以root身份运行,则可能会感到惊讶:)
pkill
。另一个原因是它与配对pgrep
,这使得更容易准确地检查将杀死哪些进程,并且哪个本身具有比更好的匹配语义ps | grep
。
“全部结束”将是killall -s SIGQUIT [process name]
。如果您想要一个理想的解决方案,请定义alias endall='killall -s SIGQUIT'
。
SIGQUIT
就像制作流程一样abort(3)
:先转储核心,然后终止流程。这绝对不比SIGTERM
的默认值更好/更温顺/更亲民killall
。
SIGQUIT
(甚至更好SIGINT
)可以比对待“软”的处理SIGTERM
,但这取决于应用程序。未经处理,它们中的任何一个都会立即终止。