실행해야 할 작업이 수십 개 또는 수백 개 있지만 CPU를 많이 사용하고 동시에 몇 개의 작업만 실행할 수 있다고 가정해 보겠습니다. X
작업을 즉시 실행하고 완료되면 새 작업을 시작하는 쉬운 방법이 있습니까 ? 내가 생각할 수 있는 유일한 것은 다음과 같습니다(의사 코드).
jobs=(...);
MAX_JOBS=4;
cur_jobs=0;
pids=(); # hash/associative array
while (jobs); do
while (cur_jobs < MAX_JOBS); do
pop and spawn job and store PID and anything else needed;
cur_jobs++;
done
sleep 5;
for each PID:
if no longer active; then
remove PID;
cur_jobs--;
done
나는 종종 그렇듯이 내 솔루션이 너무 복잡하다고 느꼈습니다. 모든 어려운 작업을 수행하는 포트가 있을 수 있는 경우 대상 시스템은 FreeBSD이지만 일반적인 솔루션이나 일반적인 관용구가 더 좋습니다.
답변1
GNU Parallel이 있다면 다음과 같이 할 수 있습니다:
parallel do_it {} --option foo < argumentlist
GNU Parallel은 동일한 컴퓨터 또는 SSH를 통해 액세스할 수 있는 여러 컴퓨터에서 작업을 병렬로 쉽게 실행할 수 있게 해주는 범용 병렬 처리기입니다.
4개의 CPU에서 32개의 서로 다른 작업을 실행하려는 경우 병렬화하는 간단한 방법은 각 CPU에서 8개의 작업을 실행하는 것입니다.
대신, GNU Parallel은 작업이 완료되면 새로운 프로세스를 생성하여 CPU를 활성 상태로 유지하여 시간을 절약합니다.
설치하다
배포판에 GNU Parallel이 패키지되어 있지 않으면 루트 액세스 없이 개인 설치를 수행할 수 있습니다. 이 작업은 10초 안에 완료할 수 있습니다.
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
다른 설치 옵션은 다음을 참조하세요.http://git.savannah.gnu.org/cgit/parallel.git/tree/README
더 알아보기
더 많은 예시 보기:http://www.gnu.org/software/parallel/man.html
소개 비디오 보기:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
이 튜토리얼을 살펴보세요:http://www.gnu.org/software/parallel/parallel_tutorial.html
지원을 받으려면 이메일 목록에 가입하세요.https://lists.gnu.org/mailman/listinfo/parallel
답변2
할 수는 있지만 까다롭고 취약합니다. 여러 가지 옵션이 있는데 그 중 하나가 입니다 xargs
.
이 흥미로운 기사는 작업 제어 및 신호에 의존할 때 발생하는 문제에 대해 설명하며 실제로 읽을 가치가 있습니다.
http://prll.sourceforge.net/shell_parallel.html
이 사람은 prll
모든 입력과 출력을 동기화하는 제어 프로세스를 사용하여 임의의 셸 기능을 병렬로(자동 감지 또는 사용자 정의 풀 크기 사용) 실행할 수 있는 새로운 도구를 만든 것으로 보입니다.
여기에서 확인해보세요: https://gitorious.org/prll/pages/Home
답변3
저도 님과 똑같은 상황인데 병렬로 실행해야 하는 작업은 Ruby 스크립트를 실행하는 명령입니다. 먼저 그것이 완벽하지 않고 오히려 깨지기 쉽다는 점을 인정해야 합니다.
제가 루비코드에서 한 일은,
counting_process = IO.popen "ps -e | grep 'YourCMDPattern' -c"
count_of_processes = counting_process.readlines[0].to_i
그런 다음 while 루프에서 주기적으로 프로세스 수를 확인한 다음, 그 수가 유지하려는 병렬 실행 수 아래로 떨어지면 Ruby의 IO.popen을 사용하여 특정 수의 새 프로세스를 실행하는 셸 명령을 트리거합니다.
내가 실행해야 하는 쉘 명령은 동적이며 Ruby 코드에서 생성된 변수를 포함하므로 Ruby 스크립트에서 이 작업을 수행해야 합니다.
Ruby가 관련되지 않으면 GNU Parallel이 더 나은 선택인 것 같습니다.