Bash: 고정된 수의 프로세스를 기다립니다.

Bash: 고정된 수의 프로세스를 기다립니다.

Java jar를 실행하는 bash 스크립트를 작성했습니다.N빈도.

실제로 나는 e를 정의합니다.부자()통화를 포함한 기능할 수 있다, 그런 다음 이 스크립트를 실행합니다.

for RUN in $(seq 1 $RUNS) 
do 
    foo & 
done

이제 처형하고 싶지 않아요달리다병렬 시간할 수 있다. 병렬 실행 수에 대기 제한이 있습니까(예: wait프로세스 10개마다)?

답변1

bash버전 4.4에서는 다음과 같은 유용한 새 관용구가 도입되었습니다.매개변수 변환이 경우 도움이 될 수 있습니다. 아래 코드 조각에서 ${num_jobs@P}이는 @P유형이라는 점에 유의하세요.매개변수 변환이로 인해 변수가 프롬프트 문자열처럼 확장됩니다 bash. man bash다른 보기매개변수 변환옵션.

#!/bin/bash
num_procs=$1
num_iters=$2
num_jobs="\j"  # The prompt escape for number of jobs currently running
for ((i=0; i<num_iters; i++)); do
  while (( ${num_jobs@P} >= num_procs )); do
    wait -n
  done
  foo &
done

Cheppner에 대한 크레딧https://stackoverflow.com/a/38775799/6631810.


Kusalananda의 의견에 따르면 필요한 경우 이 프로세스 세트를 개수에 영향을 미치는 다른 백그라운드 작업과 독립적으로 만들기 위해 자체 셸에 래핑할 수 있습니다. 이렇게 하려면 몇 가지 변경이 필요합니다.

#!/bin/bash
# start a wrapper shell for the group of jobs
cat<<EOS | bash &
num_procs="$1"
num_iters="$2"
for ((i=0; i<num_iters; i++)); do
  # escape what's not supposed to be expanded
  # at the time of here-doc redirection
  while (( \${num_jobs@P} >= num_procs )); do  
    wait -n
  done
  foo &
done
EOS
# now you can do other things

답변2

for RUN in $(seq 1 $RUNS); do
    foo &

    if (( (RUN % 10) == 0 )); then
        wait
    fi
done

또는 대체 루프 구성을 사용하십시오(IMHO가 더 좋아 보입니다).

for (( r = 1; r <= RUNS; ++i )); do
    foo &

    if (( (r % 10) == 0 )); then
        wait
    fi
done

10의 배수가 아닌 경우 wait루프 뒤에 별도의 값을 추가할 수도 있습니다.$RUNS


RUNS총 실행 횟수 외에도 n10개의 작업 배치를 상상할 수도 있습니다.

for (( i = 0; i < n; ++i )); do
    printf 'starting batch %d...\n' "$i"
    for (( j = 0; j < 10; ++j )); do
        foo &
    done

    echo 'waiting...'
    wait
done

xargs사용하고 명시적인 대체 솔루션이 없습니다 wait.

seq 1 "$RUNS" | xargs -n 1 -P 10 foo

그러나 이는 프로세스 에 필요하지 않을 수 foo있는 명령줄 인수(생성된 정수 중 하나)를 제공합니다. seq이렇게 하면 문제가 해결됩니다.

seq 1 "$RUNS" | xargs -n 1 -P 10 sh -c 'foo'

답변3

GNU Parallel은 정확히 다음을 위해 설계되었습니다:

seq 1 $RUNS | parallel -j 10 -N0 foo

기본적으로 CPU 코어당 하나의 작업이 실행됩니다.

seq 1 $RUNS | parallel -N0 foo

GNU Parallel은 동일한 컴퓨터 또는 SSH를 통해 액세스할 수 있는 여러 컴퓨터에서 작업을 병렬로 쉽게 실행할 수 있게 해주는 범용 병렬 처리기입니다.

4개의 CPU에서 32개의 서로 다른 작업을 실행하려는 경우 병렬화하는 간단한 방법은 각 CPU에서 8개의 작업을 실행하는 것입니다.

간단한 스케줄링

대신, GNU Parallel은 작업이 완료되면 새로운 프로세스를 생성하여 CPU를 활성 상태로 유지하여 시간을 절약합니다.

GNU 병렬 스케줄링

설치하다

보안상의 이유로 패키지 관리자를 사용하여 GNU Parallel을 설치해야 하지만 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

관련 정보