병렬 프로세스를 실행하고 둘 다 완료되었을 때 출력을 결합하는 방법


17

약 5 또는 6 개의 다른 프로그램을 통해 일부 데이터를 파이프 한 다음 최종 결과를 탭으로 구분 된 파일로 만드는 bash 쉘 스크립트가 있습니다.

그런 다음 별도의 유사한 데이터 세트에 대해 동일한 작업을 다시 수행하고 두 번째 파일로 출력합니다.

그런 다음 두 파일 모두 비교 분석을 위해 다른 프로그램에 입력됩니다. 예를 들어

Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv
AnalysisProg -i Data1res.csv Data2res.csv

내 질문은 : 어떻게 step1과 step2를 동시에 (예를 들어 &를 사용하여) 실행할 수 있지만 둘 다 완료되면 step3 (AnalysisProg) 만 시작할 수 있습니까?

고마워

ps AnalysisProg는 스트림 또는 fifo에서 작동하지 않습니다.


이것을 확인하십시오 : pebblesinthesand.wordpress.com/2008/05/22/…
— Bichoy

BTW, Perl 스크립트를 사용해도 되나요? 이를 통해 문제를 크게 단순화 할 수 있으며이 사후 처리를 매우 효율적으로 구현하고 손쉽게 병렬로 실행할 수 있습니다.
— Bichoy

Perl ..별로, 아니 :(
— Stephen Henderson

1
여기에서는 tee두 개의 동시 grep프로세스로 파이프를 통해 입력을 분할 하고 처리 하는 방법을 보여줍니다 . unix.stackexchange.com/questions/120333/…
— mikeserv

그리고 여기에서는 간단한 쉘 구조를 사용하여 프로세스를 완전히 백그라운드로 처리 nohup하지만 프로세스와의 통신 수단을 유지하는 방법을 보여줍니다. unix.stackexchange.com/questions/121253/…
— mikeserv

답변:


27

사용하십시오 wait. 예를 들면 다음과 같습니다.

Data1 ... > Data1Res.csv &
Data2 ... > Data2Res.csv &
wait
AnalysisProg

의지:

  • 백그라운드 작업으로 Data1 및 Data2 파이프를 실행하십시오.
  • 둘 다 끝날 때까지 기다리세요
  • AnalysisProg를 실행하십시오.

예를 들어이 질문을 참조하십시오 .


Thx, 좋아 보인다. 위의 방법으로 문제가 해결되지 않으면 시도해 보겠습니다.
— Stephen Henderson

들으 다시, 나는 일종의 대기의 인식의했지만 조금 지금은 그냥 "대기"입니다 참조는 다른 PID 등 I 느낌 바보와 협력하는 방법에 혼란스러워했다 봤 한
— 스티븐 헨더슨

12

cxw의 대답은 의심 할 여지없이 2 개의 파일 만 있으면 선호되는 솔루션입니다. 2 개의 파일이 단지 예이고 실제로 10000 개의 파일이있는 경우 '&'솔루션이 작동하지 않아 서버에 과부하가 발생합니다. 이를 위해서는 GNU Parallel과 같은 도구가 필요합니다.

ls Data* | parallel 'cat {} | this | that |theother | grep |sed | awk |whatever > {}res.csv
AnalysisProg -i *res.csv

GNU Parallel에 대해 더 배우려면 :


안녕하세요 thx. 현재 두 개의 파일이 있지만 24 개의 프로세서가 있으므로 한 번에 여러 쌍을 시도해보고 싶은 유혹을 느꼈습니다.하지만 컴퓨팅 과학 전문가는 아니지만 디스크 읽기 병목 현상이 가치가 있는지는 확실하지 않습니다. 어쩌면 내가 그것을 빨아보고;)
— Stephen Henderson

@StephenHenderson은 크기에 따라 파일이 여전히 캐시에있을 수 있습니다. 속도가 중요한 경우 tmpfs를 사용할 수 있습니다 (파일은 <<<이고 RAM입니다).
— Maciej Piechotka

1
@StephenHenderson 병렬 작업의 수는 -j를 사용하여 조정할 수 있으므로 -j4를 시도하고 서버에 과부하가 걸리지 않으면 -j6 등을 시도하십시오. 그러나 CTRL-C를 누를 준비가되었습니다. GNU Parallel은 서버를 빠르게 과부하시키는 훌륭한 도구입니다. . --load도 살펴보십시오.
— Ole Tange

1

이를 수행하는 한 가지 방법은 다음과 같습니다.

AnalysisProg <<PREPROCESS /dev/stdin
$( 
{   process1=$( pipe | line | 1 >&2 & echo $! )
    process2=$( pipe | line | 2 >&2 & echo $! )
    while ps -p $process1 $process2 >/dev/null; do
        sleep 1
    done
} 2>&1
)
#END
PREPROCESS

이런 식으로 두 파이프 라인을 모두 배경으로하지만 출력을 여기 문서에서 평가하여 AnalysisProg로 전달하기 전에 stdin에 출력을 결합하기 전에 실행을 완료 할 때까지 기다리십시오. wait이것을 사용할 수 있다면 while ps루프 보다 낫지 만 쉘에 따라 현재 쉘의 자식이 아닌wait 프로세스에서 대기하도록 지시하면 객체를 거부 할 수 있습니다 .

또한 위의 방법은 출력을 수집하므로 두 프로세스 모두 한 번에 작성됩니다. 대신에 그것들을 별도로 원하거나 다른 것에 추가하려면 다음을 수행하십시오.

AnalysisProg 3<<PREPROCESS /dev/fd/3 /dev/stderr
$(
process1=$(... >&2 ...) 2>/dev/fd/3
...
} 3>/dev/fd/3 2>/dev/stderr
)

이전에 이러한 개념을 시연했습니다. 아마도 최고의 데모가 여기 에 있습니다 .


0

이것을 사용해보십시오.

rm -f Data1Res.csv
rm -f Data2Res.csv
Data1 | this | that |theother | grep |sed | awk |whatever > Data1Res.csv &
Data2 | this | that |theother | grep |sed | awk |whatever > Data2Res.csv &
while true
do
  ps aux | grep -v grep | grep -i -E 'Data1Res.csv|Data2Res.csv' &> /dev/null
  if [ $? -ne 0 ]
  then
    AnalysisProg -i Data1res.csv Data2res.csv
    exit 0
  fi
done

글쎄, 그것은 무거운 것입니다. wait의 바퀴를 재발 명하는 것과 같지 않습니까?
— John WH Smith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.