2014-05-15 1 views
1

큰 파일을 분할, 정렬 및 병합하여 정렬을 병렬 처리하려면이 blog entry을 따랐습니다. 단계는 다음과 같습니다 정렬 단계가 완료 될 때까지 2 단계와 3 사이'대기'가 분리 된 작업을 기다리지 않는 이유

  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

은, 하나는 기다려야합니다. 나는 man 페이지에 따라 wait이 인수없이 호출되었으므로 어떤 인자도없이 wait이 올바른 것이 될 것이라고 가정했습니다. all currently active child processes are waited for. topsort 프로세스가 계속 실행된다 나타내지 만

I 쉘이 시도 때 (즉, 실행 단계 1 및 2 다음 wait) 즉시 복귀 wait.

궁극적으로 나는 그걸로 스크립트의 속도를 높이고 싶습니다. 그래서 쉘에서 수동으로 할 수있는 일은 아닙니다.

나는 이 버전 8부터 --parallel 옵션을 가지고 있지만, 나는 이것을 실행하고 이전 버전이 설치되어 있으며이 문제를 해결하는 방법에 대해서도 궁금하다. the bash man page 가입일

+0

'1! ... | FILE 읽기 '가 잘못되었습니다. _tmp *에서'for FILE을 사용하십시오; 대신 '할'. – chepner

답변

3

여기에 귀하의 문제를 재현하는 간단한 테스트 케이스이다 :

true | { sleep 10 & } 
wait 
echo "This echos immediately" 

문제는 파이프가 서브 쉘을 생성하고, 갈래의 프로세스가 일부이다 그 서브 쉘의 이 솔루션은 메인 부모 쉘 대신 그 서브 쉘에서 대기하는 것입니다 : 코드로 다시 번역

true | { sleep 10 & wait } 
echo "This waits" 

,이 의미

ls -1 _tmp* | { while read FILE; do sort $FILE -o $FILE & done; wait; } 
1

: 파이프 라인에서 각 명령은 (서브 쉘에서, 즉)는 별도의 프로세스로 실행

.

그래서 while으로 파이프하면 서브 쉘이 만들어집니다. 2 단계의 다른 모든 것은이 서브 쉘 내에서 실행됩니다 (즉 모든 백그라운드 프로세스). 그런 다음 스크립트는 while 루프를 종료하고 서브 쉘을 종료하고 wait이 상위 쉘에서 실행됩니다. 여기서 기다릴 것이 없습니다. 당신은 사용하여 파이프 라인을 사용하지 않도록 할 수있는 process substitution :

while read FILE; do 
    sort $FILE -o $FILE & 
done < <(ls -1 _tmp*) 
관련 문제