Bash에서 시작된 프로그램 수 제어

Bash에서 시작된 프로그램 수 제어

저는 연구 프로젝트의 일환으로 많은 양의 데이터를 여러 파일로 분할하여 처리하고 있습니다.

폴더의 모든 파일은 폴더의 모든 요소와 관련된 스크립트로 처리되어야 foo합니다 .myScriptbar

이것은 myScript:

for f in bar/*
do
    awk 'NR==FNR{a[$0]=$0;next}!a[$0]' $f $1 > tmp
    cp tmp $1
done

모든 파일을 처리하기 위해 for 루프를 사용하는 첫 번째 아이디어는 다음과 같습니다.

for f in foo/*
do
    ./myScript $f
done

그러나 시간이 오래 걸립니다. 간단히 추가하여 백그라운드에서 각 myScript를 시작하면 &수천 개의 병렬 실행과 막대한 입력이 awk포함된 인스턴스가 생성되므로 cp분명히 좋지 않습니다.

다음을 사용하여 생성된 "스레드" 수를 제한하고 싶습니다.

for f in foo/*
do
    THREAD_COUNT=$(ps | wc -f)
    while [ $THREAD_COUNT -ge 12 ]
    do
        sleep 1
        THREAD_COUNT=$(ps | wc -f)
    done
    ./myScript $f &
done

참고로, 노드에 8개의 코어가 있고 분명히 항상 bashrunning 이 ps있고 wc호출 당시의 헤더 라인도 running 이기 때문에 12와 비교하고 있습니다 ps | wc -l.

안타깝게도 을 호출 myScript하면 여러 추가 항목이 에 나타나므로 ps내 스크립트가 예상대로 작동하지 않습니다.

제 질문은 이렇습니다. 더 쉬운 방법이 있나요? 어느 쪽이 더 안정적인가요?

노드에서 다른 작업을 수행하지 않으므로 발생하는 모든 작업은 스크립트로 인해 발생합니다.

답변1

쉘 스크립트를 사용하여 이 작업을 수행할 수 있지만 어렵습니다. 쉘 스크립트는 여러 백그라운드 작업을 수행하는 데 그다지 능숙하지 않습니다.

내 제안은 다음을 사용하는 것입니다.GNU가 만든다또는 다른 버전의 make는 -j여러 작업을 병렬로 실행하도록 선택할 수 있습니다. 각 하위 작업을 makefile 규칙으로 작성합니다.

아래 메이크파일 조각이 귀하의 규칙을 구현한 것 같지만 귀하의 코드는 따라가기가 어렵기 때문에 지금 당장 결과를 얻었을 수도 있습니다. 첫 번째 줄은 입력 파일의 출력 파일을 열거합니다(참고: 입력 파일을 덮어쓰지 마십시오! 어떤 이유로든 작업이 중간에 중지되면 처리되었는지 알 수 없는 데이터가 남게 됩니다). 들여쓰기된 줄은 실행할 명령입니다. 8개의 공백 대신 탭을 사용하여 각 명령을 들여씁니다. 이 명령에서 는 소스 파일( file) $<을 나타내고 , 대상 파일( file)을 나타내며 , 확장자가 없는 대상입니다. 셸 명령의 모든 기호는 두 배가 되어야 하며, 개행을 억제하기 위해 끝에 를 추가하지 않는 한 각 명령줄은 별도의 하위 셸에서 실행됩니다(그래서 셸에서는 시작과 끝이 하나의 긴 줄로 표시됩니다 )..in$@.out$*$\set -edone

all: $(patsubst %.in,%.out,$(wildcard foo/*.in))
%.out: %.in
        cp $< $*.tmp.in
        set -e; \
        for f in bar/*; do \
          awk 'NR==FNR{a[$$0]=$$0;next}!a[$$0]' $$f $*.tmp.in >$*.tmp.out; \
          mv $*.tmp.out $*.tmp.in; \
        done
        mv $*.tmp.in $@

Makefile이름이 지정된 파일에 넣고 호출합니다 make -j12.

답변2

GNU Parallel(http://www.gnu.org/software/parallel/)을 사용하면 다음과 같습니다.

parallel awk \'NR==FNR\{a\[\$0\]=\$0\;next\}\!a\[\$0\]\' {1} {2} '>{2}.tmp; mv {2}.tmp {2}' ::: bar/* ::: foo/*

그러면 코어당 하나의 작업이 실행됩니다. -j150%코어당 1.5개의 작업을 실행 하는 데 사용됩니다 .

여러 개를 병렬로 실행하려면 myScript다음을 수행하십시오.

parallel ./myScript ::: foo/*

자세히 알아보려면 소개 비디오를 시청하세요.https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

답변3

ulimitbash 매뉴얼 페이지에서 사용해 볼 수 있습니다 .

ulimit [-HSTabcdefilmnpqrstuvx [limit]]
Provides control over the resources available to the shell and to processes started  by  it, 
on systems  that  allow  such control.
[...]
-u     The maximum number of processes available to a single user

ulimit -u 8따라서 스크립트 내의 적절한 위치 에 넣으면 셸에서 사용할 수 있는 프로세스가 8개로 제한됩니다.

그러나 아직 테스트하지 않았습니다.

관련 정보