병렬 실행 명령을 실행하면 xargs -n 1 -P 0
출력이 모두 엉망이 됩니다. 병렬 실행을 수행하는 방법이 있지만 두 번째 실행의 출력이 시작되기 전에 첫 번째 실행의 전체 출력이 stdout에 기록되고 세 번째 실행의 출력이 시작되기 전에 두 번째 실행의 전체 출력이 stdout에 기록되는지 확인하십시오. 시작 기다리기 시작하시겠습니까?
예를 들어, 많은 양의 데이터가 포함된 많은 파일을 해시하려는 경우 다음을 수행할 수 있습니다.
printf "%s\0" * | xargs -r0 -n 1 -P 0 sha256sum
소량의 데이터(9GB)로 테스트했는데 단 5.7초 만에 끝났습니다. 다음을 사용하여 동일한 데이터를 해싱합니다.
sha256sum *
34.1초가 걸렸습니다. 많은 양의 데이터를 해시해야 하는 경우가 많으므로(몇 시간이 걸릴 수 있음) 병렬 처리를 통해 작업이 더 빨리 완료됩니다.
여기서 문제는 출력 라인의 순서가 잘못되었다는 것입니다. 이 경우 두 번째 열을 기준으로 행을 정렬하면 문제가 해결됩니다. 그러나 항상 쉬운 것은 아닙니다. 예를 들어, 위의 해싱 예제를 고수하지만 번호가 매겨진 파일을 순차적으로 해시하려는 경우 이는 이미 중단됩니다.
printf "%s\0" {1..10000} | xargs -r0 -n 1 -P 0 sha256sum
이를 위해서는 좀 더 고급 정렬이 필요합니다. 해시 예제를 완전히 벗어나면 상황이 더 복잡해집니다.
댓글에서 누군가 출력이 인터리브되는 것을 막고 싶은지 물었습니다. 그렇지 않다. 나는 질서를 유지하고 싶다.
답변1
이를 달성하기 위해 GNU Parallel()을 사용할 수 있습니다 --keep-order
.
printf "%s\0" {1..10000} | parallel --keep-order -r0 -n 1 -P 0 sha256sum
--keep-order
각 프로세스는 4개의 파일 핸들을 사용하므로 인쇄가 지연됩니다. 이로 인해 일반적으로 지연이 발생하지 않습니다.
예를 들어, 1000개의 파일 핸들이 있고 단일 작업이 평균 작업보다 250배 이상 오래 걸리는 경우 GNU Parallel은 996개의 파일 핸들을 사용하여 추가 작업을 수행합니다. 장기 실행 작업이 완료되지 않은 채로 남아 있으면 GNU Parallel은 파일 핸들이 부족하여 장기 실행 작업이 완료될 때까지 기다립니다. 다음과 같이 경고합니다.
parallel: Warning: No more file handles.
parallel: Warning: Try running 'parallel -j0 -N 100 --pipe parallel -j0'
parallel: Warning: or increasing 'ulimit -n' (try: ulimit -n `ulimit -Hn`)
parallel: Warning: or increasing 'nofile' in /etc/security/limits.conf
parallel: Warning: or increasing /proc/sys/fs/file-max
그러면 긴 작업이 완료될 때까지 일시 중지됩니다. 데이터 손실은 없습니다.