一段时间睡眠循环获得自己的pid
-
10-10-2019 - |
题
我有一个bash脚本,可以在循环中进行一些并行处理。我不希望并行过程尖峰CPU,因此我使用睡眠命令。这是一个简化的版本。
(while true;do sleep 99999;done)&
因此,我通过bash提示执行上述行,并得到类似的内容:[1] 12345
在哪里 [1]
是工作编号和 12345
是while循环的过程ID(PID)。我做一个 kill 12345
并得到:
[1]+ Terminated ( while true; do sleep 99999; done )
看起来整个脚本都已终止。但是,我做了 ps aux|grep sleep
并找到睡眠命令仍然很强,但有自己的pid!我可以杀死 sleep
一切似乎都很好。但是,如果我先杀死睡眠,那么while循环开始了一个新的 sleep
pid。这对我来说是一个惊喜,因为睡眠与时循环不平行。循环本身是执行的单一路径。
所以我有两个问题:
- 为什么睡眠命令获得自己的流程ID?
- 我如何轻松杀死循环和睡眠?
解决方案
- 睡眠有自己的
PID
因为这是一个正在运行的过程,只是等待。尝试which sleep
看看它在哪里。 - 您可以使用
ps -uf
查看系统上的过程树。从那里您可以确定什么PPID
壳的(父pid)(一个运行循环的一个)是睡眠的。
其他提示
你尝试过吗 kill %1
, , 在哪里 1
您在后台启动命令后获得的数字是吗?
发射后我现在做到了 (while true;do sleep 99999;done)&
它正确终止了它。
“ PS - PPID”使用指定的父pid选择所有过程,例如:
$ (while true;do sleep 99999;done)&
[1] 12345
$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)
您可以杀死流程组。
要查找流程的流程组运行:
ps --no-headers -o "%r" -p 15864
然后使用:
kill -- -[PGID]
您可以在一个命令中完成所有操作。让我们尝试一下:
$ (while true;do sleep 99999;done)&
[1] 16151
$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+ Terminated ( while true; do
sleep 99999;
done )
因为“睡眠”是一个过程,而不是建造功能或类似的过程
您可以做以下操作:
(while true;do sleep 99999;done)& whilepid=$! kill -- -$whilepid
以上代码杀死了过程组,因为PID指定为负数(例如-123而不是123)。另外,它使用变量 $!
, ,它存储了最近执行的过程的PID。
注意:当您在交互式模式下执行任何过程(即使用命令行提示符)时,它会创建一个新的进程组,这就是您正在发生的事情。这样,“杀死所有人”相对容易,因为您只需要杀死整个过程组即可。但是,当在脚本中完成相同的操作时,它不会创建任何新组,因为所有新进程都属于脚本PID,即使它们在后台执行(默认情况下是禁用了作业控制)。要在脚本中启用作业控制,您只需要将以下内容放在脚本的开头:
#!/bin/bash
set -m
杀死 while
循环和 sleep
使用 $!
您也可以使用 trap
子壳内部的信号处理程序。
(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}