2012-07-18 5 views
0

최종 업데이트 : 정말 어떻게 설명 해야할지 모르지만 더 이상 문제가 발생하지 않습니다. 문제를 해결하기 위해 무엇이 변했는지 파악하면 답변을 게시 할 것입니다.포크 :: 슈퍼 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_piduninitialized 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 perlpkill java을 사용하여)를 죽이고 다시 시작하면 많은 수의 오류 메시지와 작지만 산발적 인 숫자의 자식이 top에 있습니다. .

답변

1

나는 이것에 관해서 발견 한 것을 공유하고있다.

작업 스크립트에는 하나의 루프 만 포함되어 있으며 작동중인 스크립트에는 작동중인 프로세스보다 많은 프로세스가 있다고 가정 할 때 중첩 루프가 포함되어 있습니다.

sh: fork: retry: No child processes 

하위 프로세스가 더 이상 포크 할 수 없다고 말하는 시스템 오류가 없습니다. 따라서 실행시 코드가 더 많은 프로세스를 포착 할 수 있으며 이로 인해이 오류가 발생합니다.

MAX_PROC => 24 

한 번을 실행하는 24 개 과정을 제공하고 있으며, 그것은 ON_BUSY => 'block'에 따라,이 24보다 더 포크하려고하면, 그것은 대기하고하고 성공할 때까지 아이를 만들기 위해 시도합니다. 모듈 문서 Forks::Super에서 시스템 포크 호출이 실패하면 실패 할 것이라고합니다. 오류에서 당신은 시스템이 더 포크에 실패한다는 것을 분명히했습니다. $count++ 변수를 추가하고 포크 될 프로세스 수를 찾으십시오. 더 많은 단서를 얻을 수 있도록 Forks::Super::DEBUG을 시도하십시오.

$ ulimit -a은 최대 프로세스 수를 반환하지 않으며 실제로 사용자가 실행할 수있는 최대 스레드 수를 반환합니다. 지금 실행중인 프로세스를보다 명확하게 파악할 수 있도록 ps aux을 시도하십시오.

+0

감사합니다. 내일은이 문제를 조사하고 업데이트합니다. 중첩 루프는 더 많은 프로세스를 의미하지는 않습니다. 모든 프로세스는 주어진 디렉토리의 파일 수에 따라 다릅니다. 이 경우 실제로는 프로세스가 훨씬 적습니다. 또한 다른 스크립트는 수일 동안 실행되며 수만 개의 프로세스가 문제없이 포킹됩니다.이 새로운 테스트 설정으로 실행할 프로세스는 총 2,000 개에 불과합니다. 나는 Forks :: Super가 실제로 실제 작업자 프로세스를 만드는 경우를 제외하고는 fork하지 않는다고 생각하고 그렇지 않으면 매우 오랫동안 블록해야 할 때마다 실패 할 것이라고 생각한다. – kaz

+0

즉, 내가 그 모듈을 사용하는 이유 중 하나는 활성 프로세스의 수를 제어하고 MAX_PROC로 제한한다고 주장하기 때문입니다. 그렇게하지 않으면 버그를 제출해야합니다 . – kaz

+0

하지만 모듈 문서에서 알 수 있습니다. _ 시스템 포크 호출이 실패하면 실패합니다. 또한 깨진 코드를 실행 한 직후에 작업 코드를 실행하십시오. 따라서 서버가 새로운 자식을 포크 할 수 없다면 작업 코드에서 오류를 표시해야합니다. – Jithin

0

답변이 제공되지 않았기 때문에, 나는이 경험이 있기 때문에이 오래된 스레드에 소리를내어 줄 것이라고 생각했습니다. 내 Fedora 20 상자는 몇 주 동안 잘 돌아가고 있었고 금요일에 사무실을 떠났으 며 이번 월요일 아침에 xscreensaver 세션을 잠금 해제 할 수 없다는 사실을 알았습니다. 어떤 키 또는 마우스 움직임이라도 화면이 깜박 거리게됩니다. 텍스트 콘솔을 얻으려면 Ctrl-Alt-F2를 누르십시오. 로그인하고 나열한 것과 동일한 메시지가 나타납니다. 내가 발행 한 각 명령 (처음에는 sudo su -)은 "bash : fork : retry : 자식 프로세스 없음"을 주었고, 결국 명령이 완료되었습니다.

마침내 프로세스 목록을 볼 수 있었고 내 ulimit 설정이 정상 이었기 때문에 아무 것도 평소와 다르게 보였습니다.하지만 maxuprc 및 열린 파일 모두에서 제한을 초과했습니다. 메모리 사용도 괜찮았다. 한가지 주목 한 것은 파이어 폭스 프로세스 (및 파이어 폭스 플러그인 컨테이너 프로세스)가 지난 주 이후로 수백 시간 정도의 과도한 CPU 사용량을 소비하고 있다는 것입니다. 나는 그 과정들 모두를 죽였고, 그 다음에 나의 시스템은 괜찮았다.

내가 열어 본 탭이 문제가 있다고 생각 될 수도 있지만 어느 쪽이든 그 프로세스 (또는 그 중 적어도 하나)가 분명히 원인이었습니다.

희망이 있습니다.