최종 업데이트 : 정말 어떻게 설명 해야할지 모르지만 더 이상 문제가 발생하지 않습니다. 문제를 해결하기 위해 무엇이 변했는지 파악하면 답변을 게시 할 것입니다.포크 :: 슈퍼 sh : 포크 : 재시도 : 아니 자식 프로세스
필자는 16 코어 Fedora 17 시스템에서 많은 수의 비슷한 명령을 실행하는 데 사용하는 perl 스크립트를 가지고 있습니다. 지금까지 명령이 생성되는 방식을 변경해야 할 때마다 기존 스크립트 중 하나를 템플릿으로 사용하여 새 스크립트를 작성하고 이전에는 코드에 문제가 없었습니다 (글쎄, 원래 스크립트 세트, 어쨌든). 이전 스크립트가 여전히 오류없이 작동한다는 점에 유의해야합니다. 따라서 이것이 시스템 문제라고 생각하지 않고 주로 코드를 엉망으로 만든 부분에 집중하고 있습니다.
:use Forks::Super MAX_PROC => 24, ON_BUSY => 'block';
#...
foreach my $n (@FI){
if($n =~ m/^\d+$/){
#...
foreach my $f (@files){
if($f =~ m/(\d+).arff/){
print "starting interval $1 ... \n";
#...
$runMe = 'java -Xmx2048m weka.classifiers.'. $class .' -t '. $TR .' -T '. $TE .' -c 1 > '. $OUT;
fork { cmd => $runMe);
}
}
}
}
waitall;
print("\nDone!\n");
이 (일부) 스크립트의 출력 :
여기use Forks::Super MAX_PROC => 24, ON_BUSY => 'block';
#...
foreach my $fi (@FILES){
#...
$runMe = 'java -Xmx2048m weka.classifiers.'. $class .' -t '. $TR .' -T '. $TE .' -c 1 > '. $OUT;
fork { cmd => $runMe};
#...
}
waitall;
print("\nDone!\n");
깨진 스크립트의 손질 버전입니다 : 여기
는 작업 스크립트의 손질 버전입니다starting interval 12 ...
starting interval 3 ...
sh: fork: retry: No child processes
starting interval 30 ...
starting interval 6 ...
Use of uninitialized value $signal_pid in print at /usr/local/share/perl5/Forks/Super/Job.pm line 991, <DATA> line 261.
Use of uninitialized value $exec_pid in waitpid at /usr/local/share/perl5/Forks/Super/Job.pm line 918, <DATA> line 261.
오류 sh: fork: retry: No child processes
, uninitialized value $signal_pid
및 uninitialized value $exec_pid
은 겉으로보기에 임의의 지점에서 반복적으로 발언하고, 프로그램이 더 오래 실행되도록 허용하면 점점 더 많아집니다.
업데이트 :$ ulimit -a
반환 max user processes (-u) 1024
나는 포크 :: 슈퍼 설정 24 플러스 나는이 원격 시스템에서 실행하고있어 4 개 터미널보다 훨씬 더 많은 것이다. 감안할 때 다른 스크립트가 잘 작동하고이 하나는 No child processes
을 반환합니다. 두 번째 스크립트에서 작성한 모든 프로세스를 정리하거나 기다려서는 안됩니다. 첫 번째와 두 번째 스크립트 사이에 waitall
에 대한 호출이 어떻게 다른지 알 수 없습니다.
업데이트 :이 문제는 프로세스가 시간에 정리되고/죽어되지 않는 것입니다 상당히 확신
starting interval 30 ...
14694 23:24:05.735: New job created: {pid=;state=NEW;cmd=java -Xmx2048m weka.classifiers.lazy.IBk -K 3 -t /foo/arff_files/$
14703 23:24:05.735: Signal pid for 14703 is 14708
14694 23:24:05.736: fork(): {pid=;state=NEW;style=cmd;cmd=[java -Xmx2048m weka.classifiers.lazy.IBk -K 3 -t /foo/arff_file$
14694 23:24:05.736: _can_launch(): system not busy. launch ok.
14694 23:24:05.736: fork: launch approved for job
14694 23:24:05.736: Job will use /bar/.fhfork14694/.fh_007.signal to get signal pid.
14707 23:24:05.737: Executing command [ java -Xmx2048m weka.classifiers.lazy.IBk -K 3 -t /home/share/data/arff_files/trainers_l1o_curv$
Use of uninitialized value $signal_pid in print at /usr/local/share/perl5/Forks/Super/Job.pm line 991, <DATA> line 261.
Use of uninitialized value $signal_pid in concatenation (.) or string at /usr/local/share/perl5/Forks/Super/Job.pm line 995, <DATA> lin$
14707 23:24:05.737: Signal pid for 14707 is
Use of uninitialized value $exec_pid in waitpid at /usr/local/share/perl5/Forks/Super/Job.pm line 918, <DATA> line 261.
14707 23:24:05.737: waitpid returned -1, exit code of 14707 was -1 72057594037927935
starting interval 6 ...
14694 23:24:05.739: New job created: {pid=;state=NEW;cmd=java -Xmx2048m weka.classifiers.lazy.IBk -K 3 -t /foo/arff_files/$
14694 23:24:05.739: fork(): {pid=;state=NEW;style=cmd;cmd=[java -Xmx2048m weka.classifiers.lazy.IBk -K 3 -t /foo/arff_file$
14694 23:24:05.739: _can_launch(): system not busy. launch ok.
14694 23:24:05.740: fork: launch approved for job
14694 23:24:05.740: Job will use /bar/programs/.fhfork14694/.fh_008.signal to get signal pid.
14694 23:24:05.740: launch(): CORE::fork() returned undefined!
current file is 2
다음 Forks::Super::Debug => 1
옵션을 사용 는 여기에 몇 가지 대표적인 출력 새로운 프로세스의 생성. ps -aux
은 부모를 죽이기 전과 후에 모두 top
의 처음 50 줄에 나타나지는 않지만 많은 아이들이 출근한다는 것에 동의합니다. waitall;
호출은 자식이 살아있는 동안 스크립트가 종료되지 않도록하고 MAX_PROC => 24
은 한 번에 24 명 이상의 자식을 시작하지 못하도록해야하므로 주어진 순간에 너무 많은 자식이 실행되는 것을 어떻게 확인할 수 있는지 잘 모르겠습니다.
waitall
이 내 문제의 원인 인 경우 스크립트가 연속적으로 호출 될 때 문제가 악화됩니다. 이는 계속 발생하는 것으로 보입니다. 그러나 이것이 사실 인 경우, 내가 무엇을하는지 보지 말아야합니다. top
. top
을 볼 때 처음에는 24 명의 어린이가 실행되는 것을 보았고, 처음 실행이 끝난 후에는 아무도 없을 때까지 chldren 수가 감소한 것을보고 다시 실행하고 또 다른 24 명의 어린이가 실행 중입니다 ...이 다른 스크립트에서 볼 수있는 정상적인 패턴입니다. 그러나 나중에 또는 스크립트 (작업과 관련된 프로세스가 생기지 않도록 pkill perl
및 pkill java
을 사용하여)를 죽이고 다시 시작하면 많은 수의 오류 메시지와 작지만 산발적 인 숫자의 자식이 top
에 있습니다. .
감사합니다. 내일은이 문제를 조사하고 업데이트합니다. 중첩 루프는 더 많은 프로세스를 의미하지는 않습니다. 모든 프로세스는 주어진 디렉토리의 파일 수에 따라 다릅니다. 이 경우 실제로는 프로세스가 훨씬 적습니다. 또한 다른 스크립트는 수일 동안 실행되며 수만 개의 프로세스가 문제없이 포킹됩니다.이 새로운 테스트 설정으로 실행할 프로세스는 총 2,000 개에 불과합니다. 나는 Forks :: Super가 실제로 실제 작업자 프로세스를 만드는 경우를 제외하고는 fork하지 않는다고 생각하고 그렇지 않으면 매우 오랫동안 블록해야 할 때마다 실패 할 것이라고 생각한다. – kaz
즉, 내가 그 모듈을 사용하는 이유 중 하나는 활성 프로세스의 수를 제어하고 MAX_PROC로 제한한다고 주장하기 때문입니다. 그렇게하지 않으면 버그를 제출해야합니다 . – kaz
하지만 모듈 문서에서 알 수 있습니다. _ 시스템 포크 호출이 실패하면 실패합니다. 또한 깨진 코드를 실행 한 직후에 작업 코드를 실행하십시오. 따라서 서버가 새로운 자식을 포크 할 수 없다면 작업 코드에서 오류를 표시해야합니다. – Jithin