1. `killall` 已经很好了(SIGTERM)

1. `killall` 已经很好了(SIGTERM)

如何以比上述方法更温和的方式结束所有同名进程killall?我不想中断进程,但想给它们留出时间正常退出。


也可以看看:

如何在 Ubuntu 中终止进程?

在系统监视器中,杀死进程和结束进程有什么区别?

为什么 killall(有时?)需要应用两次?

总结

答案1

1. `killall` 已经很好了(SIGTERM)

killall默认发送SIGTERM。这是已经这种方法很好,它让应用程序有机会自行清理。“现在就去死吧!”方法是发送一个SIGKILL信号,这需要将其指定为选项killall。从GNU C 库:终止信号

宏:整数 信号终端

[...] 这是正常的做法礼貌地要求程序终止。


2. 系统监视器的“结束进程”同样好用(SIGTERM 也是如此)

您链接到了有关 GNOME 系统监视器的问题。它SIGTERM也用于其“结束进程”操作(我意识到我与该问题的答案相矛盾)。您可以在源代码中找到它来验证自己:

数据/菜单.ui

<item>
  <attribute name="label" translatable="yes">_End</attribute>
  <attribute name="action">win.send-signal-end</attribute>
  <attribute name="accel">&lt;Primary&gt;e</attribute>
  <attribute name="target" type="i">15</attribute>
</item>

这里的 15 是信号编号。信号 15 是SIGTERM。系统监视器SIGTERM在提出和回答其他问题之前已经使用得很好了。


技术附录(回应评论)

通过查看 Github 上的表示git blame,我们发现 GNOME 系统监视器源代码中信号的拼写方式发生了以下变化:

383007f22013 年 7 月 24 日 用 GAction 参数替换发送信号的重复代码
0e766b2d2013 年 7 月 18 日 将进程弹出菜单移植到 GAction
97674c792012 年 10 月 3 日 摆脱 ProcData 结构
38c5296c2011 年 7 月 3 日 使源文件中的缩进统一。

这些都没有从到发生改变SIGQUITSIGTERM并且最后一个是在提出链接问题之前发生的。

答案2

@hvd 的回答基本正确。为了进一步证明这一点,当您关闭计算机时,该init进程将首先发送给进程,然后在延迟一段时间后发送(如果它们尚未退出)。进程无法处理/忽略。SIGTERMSIGKILLSIGKILL

不过,更详细地说,真正的答案是你无法确定程序是否处理了它。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()这种方式的使用被认为是不可移植的 - 但它比其他方法容易得多!

另一个小注脚 - Solariskillall会尝试终止所有进程。所有进程。如果您以 root 身份运行它,那么您可能会感到惊讶 :)

答案3

“结束一切” 将是killall -s SIGQUIT [process name]。如果您想要一个奇特的解决方案,请定义alias endall='killall -s SIGQUIT'

相关内容