如何以比平时更温和的方式结束所有具有相同名称的进程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,但这取决于应用程序。未经处理,它们中的任何一个都会立即终止。