【问题标题】:Can't find process listed by `jobs` command找不到“作业”命令列出的进程
【发布时间】:2020-02-19 23:55:22
【问题描述】:

我正在使用jobs 命令来控制计算密集型进程的数量。我不想一次运行超过max_cnt 进程,并且仅在所有进程都停止时才停止。

我使用下面的 bash 脚本来完成这个。但是,即使在所有内容都已执行并停止之后,此代码也始终将一个进程列为正在运行。

此外,我在htop 的进程列表中找不到该进程。我应该做什么,或者我应该在哪里寻找echo $(jobs -p) 命令的结果列出的那个进程,以及我应该如何解决这个即使一切都停止也不会退出的问题。

#!/usr/bash

SLEEP=5
max_cnt=8

# generate a random number less than eq $1
function random {
    rand=$RANDOM
    while [ "$rand" -gt $1 ]
    do
        rand=$RANDOM
    done
}

function job {
    # resource intensive job simulated by random sleeping
    echo param1="$1",param2="$2"
    random 20
    echo Sleeping for $rand
    sleep $rand
}

for param1 in 1e-6 1e-5 1e-4 1e-3 1e-2
do
    for param2 in "ones" "random"
    do
        echo starting job with $param1 $param2
        job $param1 $param2 &
        while [ "$(jobs -p|wc -l)" -ge "$max_cnt" ]
        do
            echo "current running jobs.. $(jobs -p|wc -l) ... sleeping"
            sleep $SLEEP
        done
    done
done

while [ "$(jobs -p|wc -l)" -ge 1 ]
do
    echo "current running jobs.. $(jobs -p|wc -l) ... sleeping"
    sleep $SLEEP
    echo $(jobs -p)
done

【问题讨论】:

  • echo $(jobs -p) 是对echo 的无用用法。只需jobs -p。我认为在脚本中您必须使用set -mset +m 启用作业控制。像 xargs -P"$max_cnt" bash -c 'job "$@"' 这样使用 xargs 是一种并行工作的简单方法
  • 请参阅stackoverflow.com/a/356154/14122,了解不使用jobs 跟踪后台进程的示例。 wait 命令返回它正在等待的作业的退出状态,因此可以跟踪哪些单个作业成功和失败;如果在wait 之后添加unset "pids[$i]",则还可以计算已开始但尚未收获的作业数量可供检查。
  • 考虑使用 GNU Parallel 来并行运行作业。如果您希望一次运行 8 个作业,parallel -j8 < ListOfJobs.txt
  • 你不需要。 GNU Parallel 将为您完成。 parallel echo ::: a b c ::: 1 2 3 相当于在 a,b,c 和 1,2,3 上嵌套的 for 循环
  • GNU Parallel 可以根据 CPU 负载或内存压力为您决定调度,并在多个服务器之间分配负载,处理故障/重启,标记输出,并显示进度米...只是说。

标签: linux bash jobs


【解决方案1】:

正如 cmets 中提到的,您可能需要考虑使用 GNU Parallel,它可以让管理并行作业的工作变得更轻松。您的代码可能如下所示:

#!/usr/bin/env bash

function job {
    # resource intensive job simulated by random sleeping
    echo param1="$1",param2="$2"
    ((s=(RANDOM%5)+1))
    echo Sleeping for $s
    sleep $s
}
# export function to subshells
export -f job

parallel -j8 job {1} {2} ::: 1e-6 1e-5 1e-4 1e-3 1e-2 ::: "ones" "random"

样本输出

param1=1e-6,param2=ones
Sleeping for 1
param1=1e-5,param2=ones
Sleeping for 1
param1=1e-2,param2=ones
Sleeping for 1
param1=1e-4,param2=ones
Sleeping for 2
param1=1e-4,param2=random
Sleeping for 2
param1=1e-6,param2=random
Sleeping for 4
param1=1e-2,param2=random
Sleeping for 3
param1=1e-3,param2=random
Sleeping for 4
param1=1e-5,param2=random
Sleeping for 5
param1=1e-3,param2=ones
Sleeping for 5

还有很多其他的开关和参数:

  • parallel --dry-run ... 将向您展示它会做什么,而无需实际执行任何操作

  • parallel --eta ... 为您提供“预计到达时间”

  • parallel --bar ... 给你一个进度条
  • parallel -k ... 保持输出有序
  • parallel -j 8 ... 一次运行 8 个作业,而不是默认的每个 CPU 内核 1 个作业
  • parallel --pipepart ... 将在子进程之间拆分大量文件的内容

还请注意,GNU Parallel 可以在您网络中的其他机器上分发工作,并且它具有失败和重试处理、输出标记等...

【讨论】:

  • 谢谢! parallel 很有趣,几乎解决了我的问题。但是,我仍然对未列出的工作感到好奇,因此我会等待再接受此解决方案。
  • 哪个工作没有被列出?您可能想使用parallel -k ... 来保持输出顺序,以便您检查它。
  • 请参阅“此外,我在 htop 的进程列表中找不到该进程.....”这个问题。 parallel 很好,我想以我对jobs -p的理解来理解问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-15
  • 1970-01-01
  • 2022-10-25
  • 1970-01-01
  • 2014-09-28
  • 1970-01-01
  • 2021-10-14
相关资源
最近更新 更多