gnu 병렬: 모든 stdin을 모든 프로세스로 전달

gnu 병렬: 모든 stdin을 모든 프로세스로 전달

나는 입력을 여러 가지 방식으로 병렬로 처리하여 입력되는 결과 줄을 작성하려고 합니다. 현재 접근 방식은 다음과 같습니다.

# process_parallel.sh
read input
parallel --colsep ' ' --linebuffer 'echo $input | {}' \
 ::: 'python process1.py' ./process2.sh ./process3

컨텍스트는 다음과 같이 요약됩니다.

(sleep 1; echo "short input arriving late") | ./process_parallel.sh | ./collate_results.sh

위의 방법은 작동하지만 한 가지 중요한 단점이 있습니다. 입력을 읽을 때까지 프로세스가 시작되지 않습니다. 시간이 좀 걸릴 수 있으므로 즉시 시작하고 싶습니다. 그런 다음 전체 표준 입력을 병렬 파이프로 각각에 연결하도록 합니다.

어떻게 이를 달성할 수 있나요?

답변1

실행할 데이터가 없으면 새 작업을 시작하지 않도록 GNU Parallel에 상당한 작업이 추가되었습니다. 이는 입력을 받지 못하는 일부 프로그램이 제대로 작동하지 않기 때문입니다. 따라서 당신은 GNU Parallel의 디자인에 반대하는 작업을 하게 될 것입니다.

입력을 복제하려면 tee대체를 사용하고 처리할 수 있습니다.

cat namedpipe_or_file | tee >(process1) >(process2) >(process3) >/dev/null

process1, process2및 즉시 시작됩니다 process3. 그러나 출력이 혼합될 수 있으므로 출력을 사용해야 하는 경우 다른 파일로 리디렉션해야 합니다.

cat namedpipe_or_file | tee >(process1 > out1) >(process2 > out2) >(process3 > out3) >/dev/null

답변2

두 개의 래퍼 스크립트가 있습니다. 먼저 각 프로세스가 세 개의 파일(예: file1, file2, file3)에서 입력을 읽도록 지시하도록 process_parallel.sh를 수정합니다.

이제 다음과 같이 표준 입력을 세 개의 파일에 병렬로 보내는 두 번째 래퍼 스크립트를 작성합니다.

  #!/bins/bash
  #parallelise input
  # let's call this file parallelise
  parallel -j 3 -- "echo $1 > file1" "echo $1 > file2" "echo $1 file3"

이제 다음과 같이 작업을 시작합니다.

  ./process_parallel_sh; cat InputFile | parallelise; 

답변3

Parallel에는 --tee다음과 같이 사용할 수 있는 옵션이 있습니다.

(sleep 1; echo "short input arriving late") |\
parallel --colsep ' ' --linebuffer --pipe --tee ::: 'python process1.py' ./process2.sh ./process3 |\
./collate_results.sh

보다GNU "병렬" 티 동작을 달성하는 방법

관련 정보