저는 연구 프로젝트의 일환으로 많은 양의 데이터를 여러 파일로 분할하여 처리하고 있습니다.
폴더의 모든 파일은 폴더의 모든 요소와 관련된 스크립트로 처리되어야 foo
합니다 .myScript
bar
이것은 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개의 코어가 있고 분명히 항상 bash
running 이 ps
있고 wc
호출 당시의 헤더 라인도 running 이기 때문에 12와 비교하고 있습니다 ps | wc -l
.
안타깝게도 을 호출 myScript
하면 여러 추가 항목이 에 나타나므로 ps
내 스크립트가 예상대로 작동하지 않습니다.
제 질문은 이렇습니다. 더 쉬운 방법이 있나요? 어느 쪽이 더 안정적인가요?
노드에서 다른 작업을 수행하지 않으므로 발생하는 모든 작업은 스크립트로 인해 발생합니다.
답변1
쉘 스크립트를 사용하여 이 작업을 수행할 수 있지만 어렵습니다. 쉘 스크립트는 여러 백그라운드 작업을 수행하는 데 그다지 능숙하지 않습니다.
내 제안은 다음을 사용하는 것입니다.GNU가 만든다또는 다른 버전의 make는 -j
여러 작업을 병렬로 실행하도록 선택할 수 있습니다. 각 하위 작업을 makefile 규칙으로 작성합니다.
아래 메이크파일 조각이 귀하의 규칙을 구현한 것 같지만 귀하의 코드는 따라가기가 어렵기 때문에 지금 당장 결과를 얻었을 수도 있습니다. 첫 번째 줄은 입력 파일의 출력 파일을 열거합니다(참고: 입력 파일을 덮어쓰지 마십시오! 어떤 이유로든 작업이 중간에 중지되면 처리되었는지 알 수 없는 데이터가 남게 됩니다). 들여쓰기된 줄은 실행할 명령입니다. 8개의 공백 대신 탭을 사용하여 각 명령을 들여씁니다. 이 명령에서 는 소스 파일( file) $<
을 나타내고 , 대상 파일( file)을 나타내며 , 확장자가 없는 대상입니다. 셸 명령의 모든 기호는 두 배가 되어야 하며, 개행을 억제하기 위해 끝에 를 추가하지 않는 한 각 명령줄은 별도의 하위 셸에서 실행됩니다(그래서 셸에서는 시작과 끝이 하나의 긴 줄로 표시됩니다 )..in
$@
.out
$*
$
\
set -e
done
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
ulimit
bash 매뉴얼 페이지에서 사용해 볼 수 있습니다 .
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개로 제한됩니다.
그러나 아직 테스트하지 않았습니다.