Sleep 在 while 循环中获取自己的 pid
我有一个 bash 脚本,它在循环中进行一些并行处理。我不希望并行进程占用 CPU 资源,因此我使用 sleep 命令。这是一个简化版本。
(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 并发现 sleep 命令仍然很强大,但有自己的 pid!我可以终止睡眠,一切看起来都很好。但是,如果我先终止睡眠,则 while 循环会启动一个新的睡眠 pid。这对我来说真是一个惊喜,因为睡眠与 while 循环并不平行。循环本身是一条执行路径。
所以我有两个问题:
- 为什么 sleep 命令会获得自己的进程 ID?
- 如何轻松终止 while 循环和 sleep?
I have a bash script that does some parallel processing in a loop. I don't want the parallel process to spike the CPU, so I use a sleep command. Here's a simplified version.
(while true;do sleep 99999;done)&
So I execute the above line from a bash prompt and get something like:[1] 12345
Where [1]
is the job number and 12345
is the process ID (pid) of the while loop. I do a kill 12345
and get:
[1]+ Terminated ( while true; do sleep 99999; done )
It looks like the entire script was terminated. However, I do a ps aux|grep sleep
and find the sleep command is still going strong but with its own pid! I can kill the sleep
and everything seems fine. However, if I were to kill the sleep first, the while loop starts a new sleep
pid. This is such a surprise to me since the sleep is not parallel to the while loop. The loop itself is a single path of execution.
So I have two questions:
- Why did the sleep command get its own process ID?
- How do I easily kill the while loop and the sleep?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
PID
,因为它是一个正在运行且只是等待的进程。尝试which sleep
看看它在哪里。PID
because it is a process running and just waiting. Trywhich sleep
to see where it is.ps -uf
to see the process tree on your system. From there you can determine what thePPID
(parent PID) of the shell (the one running the loop) of the sleep is.因为“sleep”是一个进程,而不是内置函数或类似函数
您可以执行以下操作:
p>
上面的代码杀死了进程组,因为 PID 被指定为负数(例如 -123 而不是 123)。此外,它还使用变量
$!
,该变量存储最近执行的进程的PID。笔记:
当您在交互模式下(即使用命令行提示符)在后台执行任何进程时,它会创建一个新的进程组,这就是您所发生的情况。这样,“杀死所有进程”就相对容易了,因为您只需杀死整个进程组即可。但是,当在脚本中执行相同操作时,它不会创建任何新组,因为所有新进程都属于脚本 PID,即使它们在后台执行(默认情况下禁用作业控制)。要在脚本中启用作业控制,您只需将以下内容放在脚本的开头:
Because "sleep" is a process, not a build-in function or similar
You could do the following:
The above code kills the process group, because the PID is specified as a negative number (e.g. -123 instead of 123). In addition, it uses the variable
$!
, which stores the PID of the most recently executed process.Note:
When you execute any process in background on interactive mode (i.e. using the command line prompt) it creates a new process group, which is what is happening to you. That way, it's relatively easy to "kill 'em all", because you just have to kill the whole process group. However, when the same is done within a script, it doesn't create any new group, because all new processes belong to the script PID, even if they are executed in background (jobs control is disabled by default). To enable jobs control in a script, you just have to put the following at the beginning of the script:
您是否尝试过执行
kill %1
,其中1
是在后台启动命令后获得的数字?我在启动
(while true;do sleep 99999;done)&
后立即执行了此操作,并且它正确地终止了它。Have you tried doing
kill %1
, where1
is the number you get after launching the command in background?I did it right now after launching
(while true;do sleep 99999;done)&
and it correctly terminated it.“ps --ppid”选择具有指定父 pid 的所有进程,例如:
"ps --ppid" selects all processes with the specified parent pid, eg:
您可以杀死该进程组。
要查找进程运行的进程组:
然后使用以下命令终止进程组:
您可以用一个命令完成这一切。让我们尝试一下:
You can kill the process group.
To find the process group of your process run:
Then kill the process group using:
You can do it all in one command. Let's try it out:
要使用
$!
终止while
循环和sleep
,您还可以在子 shell 内使用trap
信号处理程序。To kill the
while
loop and thesleep
using$!
you can also use atrap
signal handler inside the subshell.