首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么“等待”不等待分离的任务

为什么“等待”不等待分离的任务
EN

Stack Overflow用户
提问于 2014-05-15 21:10:31
回答 2查看 72关注 0票数 1

我遵循这个博客条目,通过拆分一个大文件、排序和合并来并行排序。这些步骤是:

  1. split -l5000000 data.tsv '_tmp'
  2. ls -1 _tmp* | while read FILE; do sort $FILE -o $FILE & done
  3. sort -m _tmp* -o data.tsv.sorted

在步骤2和步骤3之间,必须等待排序步骤完成。我认为没有任何参数的wait将是正确的,因为根据man页面,如果调用wait时没有参数,那么all currently active child processes are waited for就是正确的。

但是,当我在shell中尝试这一点(即执行步骤1和2,然后是wait)时,wait会立即返回,尽管top显示sort进程仍然在运行。

最终,我想用它来提高脚本的速度,所以这不是我可以手动在shell上做的一件事。

我知道sort从版本8开始就有一个--parallel选项,但是在集群上,我正在运行这个版本,安装了一个较旧的版本,我也很好奇如何解决这个问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-15 21:42:19

下面是一个简单的测试用例,重现了您的问题:

代码语言:javascript
复制
true | { sleep 10 & }
wait
echo "This echos immediately"

问题是,管道创建一个子subshell,分叉进程是该子subshell的一部分。解决方案是在该子shell中等待,而不是在主父shell中等待:

代码语言:javascript
复制
true | { sleep 10 & wait } 
echo "This waits"

翻译回您的代码,这意味着:

代码语言:javascript
复制
ls -1 _tmp* | { while read FILE; do sort $FILE -o $FILE & done; wait; }
票数 3
EN

Stack Overflow用户

发布于 2014-05-15 21:41:35

来自手册页

管道中的每个命令都作为单独的进程执行(即在子subshell中)。

因此,当您管道到while时,将创建一个子subshell。步骤2中的其他一切都在这个子step (即所有后台进程)中执行。然后,脚本退出while循环,留下子shell,在父shell中执行wait,在父shell中没有什么可等待的。可以通过使用过程替代避免使用管道。

代码语言:javascript
复制
while read FILE; do 
    sort $FILE -o $FILE & 
done < <(ls -1 _tmp*)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23688699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档