为什么SIGTERM信号对进程组不起作用?

为什么SIGTERM信号对进程组不起作用?

[编辑] 我将整个问题的 SIGINT 改为 SIGTERM。

我有一个运行启动 jboss 的子进程脚本的脚本。

#!/bin/sh
....
start_jboss.sh &
trap 'kill -SIGTERM 0' EXIT HUP TERM INT
....

当我的脚本被杀死、终止或中断时,我想向 jboss 发送 SIGTERM 信号。但上述代码不会终止 JBoss。KILL信号会杀死 JBoss(以下代码),但 JBoss 不会释放 H2 数据库锁。在我的例子中,释放 H2 锁很重要,因此我必须使用 SIGTERM 信号。

#!/bin/sh
....
start_jboss.sh &
trap 'kill -9 0' EXIT HUP TERM INT
....

我的 JBoss 使用端口 8080,因此以下命令给我一个 JBoss pid:

sudo netstat -lnpt | grep 8080

如果我执行以下命令:

 kill -SIGTERM jboss_pid_from_netstat_command

然后 JBoss 中断并释放 H2 数据库锁。

如何修改我的陷阱操作以SIGTERM向 JBoss 发送信号?我不知道为什么 SIGKILL 有效而 SIGTERM 无效。

[编辑] 我将整个问题的 SIGINT 改为 SIGTERM。

编辑

JBoss 启动脚本 ( ) 如果未设置,则standalone.sh在前台进程中启动 JBoss ;如果设置了此变量,则在后台进程中启动 JBoss。因此,我在脚本中设置了此变量。然后,以下脚本可以正常工作:LAUNCH_JBOSS_IN_BACKGROUND

#!/bin/sh
....
export LAUNCH_JBOSS_IN_BACKGORUND=a
standalone.sh &
trap 'kill -SIGTERM 0' EXIT HUP TERM INT
....


#!/bin/sh
....
export LAUNCH_JBOSS_IN_BACKGORUND=a
standalone.sh &
trap 'kill -SIGTERM $(jobs -pr)' EXIT HUP TERM INT
....


#!/bin/sh
....
export LAUNCH_JBOSS_IN_BACKGORUND=a
standalone.sh &
jboss_script_id=$!
trap 'kill -SIGTERM $jboss_script_id' EXIT HUP TERM INT
....

我仍然不知道为什么以下代码不起作用。我在 Centos 上使用 bash 工作。我在 Ubuntu 上使用 dash 进行了测试,以下代码有效,但core dump会引发警告。

(不行)

#!/bin/sh
....
standalone.sh &
trap 'kill -SIGTERM 0' EXIT HUP TERM INT
....

或(不起作用)

#!/bin/sh
....
standalone.sh &
trap 'kill -SIGTERM $(jobs -pr)' EXIT HUP TERM INT
....

或(不起作用)

#!/bin/sh
    ....
    standalone.sh &
    jboss_script_id=$!
    trap 'kill -SIGTERM $jboss_script_id' EXIT HUP TERM INT
    ....

答案1

jboss 服务器可能有一个终止处理程序,以防在处理 I/O(例如写入数据库)期间被中断。可以处理TERMINT信号,以确保当信号到达且进程忙于执行 I/O 时数据库不会损坏。

没有SIGKILL任何宽限期 - 无论进程正在做什么,都会被无情地执行。SIGKILL 信号不允许任何处理程序。除非别无选择,否则这可能是避免使用 kill -9 终止进程的重要原因。

由于某种原因,终止整个进程组会干扰正确终止和删除数据库锁定。尝试像这样终止 jboss 服务器 - 注意,您可能需要扩展 kill 命令以确保脚本的所有子脚本也终止(我不知道您的整个脚本)。

trap 'kill -SIGTERM $(jobs -pr)' EXIT HUP TERM INT

这将杀死 jboss,因为该jobs命令将返回从 shell 运行的后台进程(即您的情况下的 jboss 进程)。

答案2

我遇到过同样的问题。

如果您想终止正在运行的valgrind进程,Ctrl+C将无法执行此操作。

由于valgrind处理一些信号,我们可以向它发送信号以便它能够执行某些操作。如果您不知道信号列表,您可以通过以下方式检查(在终端上):

your_user_name:Directory$ kill -l

此命令将列出所有可用的信号。

  1. 使用 valgrind 运行你的程序(例如valgrind --tool=memcheck ./prog:)

  2. 在左侧检查 valgrind PID。示例:==938== Memcheck,内存错误检测器

  3. 打开另一个终端窗口:kill -SIGTRAP 938

这应该对你有用。

如果它对您不起作用,您可以尝试发送一些其他信号,我相信您会找到一个中断信号valgrind但仍然会打印出报告。

相关内容