【问题标题】:sem --wait does not wait after a while loop that reads from a filesem --wait 在从文件读取的while循环之后不等待
【发布时间】:2021-06-03 20:30:54
【问题描述】:

我正在尝试在 bash 中使用 GNU 并行来并行运行程序的多个实例,每个实例具有不同的参数。此外,我希望能够从文件中读取这些参数,并让脚本等待所有并行化作业完成。 GNU parallel 的 parallel --semaphore,又名 sem,似乎是一种简单的方法。

MCVE

使用来自sem 文档的basic example 的修改版本,我创建了一个最小的测试用例来说明我的问题:

while read i; do
    echo -n "$i "
    sem -j 4 "sleep $i && echo $i finished"
done < args.txt
echo
echo 'Started wait'
sem --wait
echo 'Done waiting'

这里,args.txt 是一个文件,它只包含:

1
2
3
4

预期与实际产出

我希望看到类似于以下内容的输出:

user@host:~$ ./test-sem.sh
1 2 3 4 
Started wait
1 finished
2 finished
3 finished
4 finished
Done waiting

然而,令人惊讶的是,sem --wait 实际上并没有等待任务完成,而是得到如下输出:

user@host:~$ ./test-sem.sh
1 2 3 4 
Started wait
Done waiting
user@host:~$ 1 finished
2 finished
3 finished
4 finished

也就是说,脚本执行并终止,然后sem作业在后台运行并打印它们各自的输出!为什么会这样?在 while 循环内初始化所有 sem 作业后,如何让 sem --wait 实际等待?

有趣的是,从文件中读取是导致问题的原因,而不是 while 循环本身。也就是说,以下内容按预期工作:

i=1;
while (( $i <= 4 )); do
    echo -n "$i "
    sem -j 4 "sleep $i && echo $i finished"
    let i=i+1
done
echo
echo 'Started wait'
sem --wait
echo 'Done waiting'

但我的实际用例有一个包含更复杂参数组合的文件,所以我真的很想从文件中读取参数。

【问题讨论】:

    标签: bash parallel-processing gnu-parallel


    【解决方案1】:

    来自gnu parallel docs

    --信号量

    • [...]

    • --semaphore 暗示 --semaphorename tty 除非 --semaphorename 是 指定。

    --信号量名称 --id 名称

    使用名称作为信号量的名称。默认是控制 tty 的名称(从 tty 输出)。

    默认值通常在交互使用时按预期工作,但在脚本中使用时应设置名称。 $$ 或 my_task_name 通常是一个不错的值。

    信号量存储在~/.parallel/semaphores/

    您必须使用相同的名称才能使信号量相同!以下代码:

    while read i; do
        tty
    done < somefile
    tty
    

    输出:

    not a tty
    /dev/pts/0
    

    所有tty 都会在stdin 上调用ttyname。因为标准输入来自文件,所以不再一样。你可以:

    • 使用--id &lt;some unique name&gt;手动传递名称
    • 使用不同的文件描述符while read -u 3 ...; do ..; done 3&lt;file

    【讨论】:

    • 我明白了!所以sem 默认使用tty 作为信号量名称(所以我猜,在给定终端中运行的所有 sem 命令都相互链接)。但是当我从文件中读取时,tty 会发生变化,因为它与标准输入相关联:这甚至发生在脚本之外,即终端上,与文档建议的相反。希望sem 联机帮助页更好地记录了这个问题 - 似乎它应该是一个相当常见的用例!使用 sem --id test &lt;program&gt;sem --wait --id test 可以,谢谢!
    猜你喜欢
    • 2015-07-18
    • 2012-05-20
    • 2017-09-12
    • 2020-10-31
    • 2022-01-21
    • 2016-12-05
    • 2018-08-02
    • 2010-12-26
    • 1970-01-01
    相关资源
    最近更新 更多