我正在运行一堆 shell 脚本,例如parallel -a my_scripts bash
在某个时候,我决定我已经运行了足够多的工作,并希望停止产生新的工作,只是让所有现有的工作完成。换句话说,我想在不杀死孩子的情况下杀死父进程。
在第一次启动 GNU 并行时似乎有一些控制终止的方法(例如,如果我事先知道我只想运行x
作业,那么我可以使用--halt now,success=x
参数(,但是当 GNU 并行已经在运行时,我找不到如何控制它。
当然,我可以CTRL+C
杀死并行,并重新运行中止的作业,但我认为可能有更聪明的方法。
更新:
如果您有新版本的并行>= 20190322
:根据@Bowi的评论,"自 2019 年以来,它不再SIGTERM
,而是SIGHUP
:
kill -HUP $PARALLEL_PID
SIGTERM
现在终止了孩子们,不让他们完成。
看:
- https://superuser.com/questions/1660301/gnu-parallel-is-behaving-differently-on-sigterm-in-two-cygwin-installation
- http://git.savannah.gnu.org/cgit/parallel.git/tree/NEWS#n687
原答案:
我想通了。答案是简单地将SIGTERM
发送到父parallel
进程(只需kill
其PID即可(。 然后parallel
响应以下内容(在本例中,我正在运行 4 个作业(:
parallel: SIGTERM received. No new jobs will be started.
parallel: Waiting for these 4 jobs to finish. Send SIGTERM again to stop now.
我把它从手册页中挖出来:
完成正在运行的作业但不启动新作业
如果您后悔 开始很多工作,你可以简单地打破GNU并行,但是如果你 想要确保你没有半完成的工作,你应该 将信号 SIGTERM 并行发送到 GNU:基洛尔 - 术语平行
这将告诉 GNU 并行不要启动任何新作业,而是等待 直到当前正在运行的作业完成,然后再退出。
如果您在简单的脚本中使用并行,则进行少量添加:
如果您在一个简单的 script.sh 中使用并行(<= 20190322(,如下所示:
#!/bin/bash
cd $(dirname $0)
seq -w 0 $(($1-1)) | parallel -j+0 --progress ./something.exe {}
您可以查找 script.sh 子进程的 PID(使用pgrep -P $scriptsh_pid
(,然后使用
kill -TERM $child_process_pid
如果我只在我的外壳中运行 script.sh,killall -TERM perl
也可以工作。