~6500개의 디렉토리에서 간단한 Python 스크립트를 실행하고 싶습니다. 가장 간단하고 효율성이 떨어지는 방법은 다음과 같습니다.
for d in *_directorynumber; do (cd "$d" && cp ../script.py . && python ./script.py );done
이것은 분명히 영원히 걸립니다. 대신 병렬로 실행해 보았습니다.
task(){
cd "$d" && python ./script.py .
}
그런 다음 다음과 같이 이 작업을 실행합니다.
for d in *_directorynumber; do
task "$d" &
done
약 500번 실행한 후 다음 오류가 발생합니다.
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
이것을 병렬화하는 다른 방법이 있습니까?
답변1
프로세스 수는 제한되어 있습니다. 명령을 사용하여 표시할 수 있습니다 ulimit -u
. 동일한 명령을 사용하여 늘릴 수 있습니다. 공유 컴퓨터라면 이 작업을 수행할 수 있는 권한이 없을 수도 있습니다.
6500개의 프로세스를 병렬로 실행하는 것은 아마도 나쁜 생각일 것입니다.
- 6500개의 프로세스에는 RAM이 필요합니다.
- 작업이 CPU 바인딩된 경우 더 많은 컨텍스트 전환이 필요하기 때문에 속도가 느려집니다.
- 작업이 I/O 바인딩된 경우 6500개의 프로세스가 서로 다른 디렉터리에 액세스하면 속도가 느려집니다.
귀하의 작업은 일부 병렬 프로세스의 이점을 누릴 수 있지만 보유하고 있는 CPU 코어 수의 작은 부분으로 제한해야 합니다.
답변2
노력하다:
parallel 'cd {} && cp ../script.py . && python ./script.py' ::: *_directorynumber
script.py
모든 작업이 완료될 때까지 CPU 스레드당 하나씩 실행 됩니다 .
CPU 바인딩이 아닌 경우 script.py
다음 명령을 사용하여 작업 수를 조정할 수 있습니다 --jobs
.
--jobs 10
정확히 10개를 병렬로 실행--jobs 200%
2x CPU 스레드를 병렬로 실행--jobs 0
한도(예: )에 도달할 때까지 최대한 많이 실행한-bash: fork: retry: No child processes
다음 해당 한도 미만을 유지하세요.