나는 우분투 리눅스 머신에서 실행중인 PHP 스크립트를 가지고있다. 이 스크립트는 pcntl_fork()
함수를 사용하여 여러 프로세스를 생성하고 pcntl_waitpid()
함수를 사용하여 해당 함수가 종료되었음을 기록합니다. 이 VERY (종종 약 40-50/초라고 추정 됨), 을 생성하지만이 프로세스는 각각 즉시 (나는 exit()
과 posix_kill(${pid}, SIGKILL)
을 사용해 보았습니다. 스크립트는 수 초 동안 잘 동작하지만 (10 초에서 30 초 정도), 필연적으로 '자식'프로세스 생성이 중단되고 중지됩니다. 스크립트로 인한 컴퓨터의 메모리 사용량은 증가하지 않지만 Ctrl-C로 스크립트를 강제 종료 할 때까지 스크립트가 중단되면 컴퓨터의 CPU가 천천히 증가합니다. 각 프로세스는 한 줄의 텍스트를 구문 분석하고 마지막으로 파일에 저장합니다. 테스트 목적으로, 나는 자식 프로세스를 생성하자마자 바로 종료한다. 한 테스트에서 1400 개의 프로세스가 성공적으로 시작되고 스크립트가 중단되기 전에 종료되었습니다.PHP에서 전역 프로세스 생성 제한은 무엇입니까?
나는 기계가 ulimit을 가지고 있다는 것을 알고 있지만, 프로세스의 수를 제한한다고 읽었다 고 나는 믿는다. 이 스크립트는 생성되는 즉시 하위 프로세스를 종료하므로 어떤 일이 일어나고 있는지 혼란 스럽습니다.
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 29470 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 29470 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
스크립트를 실행하는 동안 생성 프로세스의 총 수를 결정 PHP 글로벌 한계가있다 : 여기 내 현재 ulimit를 구성 (ulimit -a
)의 출력은? **이 자식 프로세스는 즉시 종료되므로이 문제는 시스템 리소스를 도용하는 프로세스를 무제한으로 만드는 문제는 아니라고 생각합니다. 나는이
$this->process_control->fork(array($this, "${FUNCTION_NAME}"), array(STRING_LINE), false);
기능을 분기하는 과정과 포크를 초기화
: 여기
는 일부 소스 코드입니다. 이 경우 $ callback은 적절한 클래스에서 호출 할 함수의 이름입니다. $ params는 $ callback에 지정된 함수에 전달할 매개 변수의 배열입니다.public function fork ($callback, $params = null, $hang = true) { $this->logger->write_log('log', "Entered fork function!"); // Evaluate the return value of the fork switch ($pid = pcntl_fork()) { case -1: // Failed $this->logger->write_log('error', "Could not fork!"); exit(1); break; case 0: // Child created succesfully $this->logger->write_log('log', "Entered child function!"); $this->logger->write_log('log', 'child ' . posix_getpid() . ' started'); if (empty($callback)) { $this->logger->write_log('warn', "Callback empty, nothing to do!"); exit(1); } if (is_array($callback) && is_array($params)) { if (!call_user_func_array($callback, $params)) { $this->logger->write_log('error', "Daemonized process returned false!"); exit(1); } else { exit(0); } } else { if (!call_user_func($callback, $params)) { $this->logger->write_log('error', "Daemonized process returned false!"); exit(1); } else { exit(0); } } break; default: // Parent $this->logger->write_log('log', "Entered parent function!"); if ($hang != true) { $this->wait($pid, false); } else { $this->wait($pid); } break; } } public function wait($p_id, $hang = true) { if ($hang) { $pid = pcntl_waitpid($p_id, $status); } else { $pid = pcntl_waitpid($p_id, $status, WNOHANG); } switch($pid) { case -1: case 0: $this->logger->write_log('log', "child exited"); break; default: $this->logger->write_log('log', "child $pid exited"); break; } }
실제로 텍스트 줄 처리 기능.
이 너무 많은 코드가있는 경우public function FUNCTION_NAME($line) { $this->logger->write_log('info', 'entered FUNCTION_NAME function'); $start_time = microtime(true); try { # check to see that the JSON line is not malformed $line_array = json_decode($line, true); if (!isset($line_array)) { throw new Exception('Could not successfully process line'); } # save the contents to disk if (!file_put_contents(FILE_NAME, $line, LOCK_EX)) { throw new Exception('file could not be saved'); } $this->logger->write_log('info', 'saved line'); return true; } catch (Exception $e) { $this->logger->write_log('error', $e->getMessage()); $this->logger->write_log('error', '----------------------------------------------------'); $this->logger->write_log('error', var_export($line, true)); $this->logger->write_log('error', '----------------------------------------------------'); file_put_contents(ERROR_SRC_FILE, $line, FILE_APPEND); return false; } }
죄송합니다, 원래의 질문에 대답하기 위해, 나는에 대한 제한이 발견되지 않은 나에게 질문
'각 프로세스는 한 줄의 텍스트를 구문 분석하고 마지막으로 파일에 저장합니다. '- 완전히 새로운 프로세스가 필요한 것처럼 들리지는 않습니다. 왜이 방법을 사용하는지 느껴 집니까? ? – DaveRandom
코드, 부모 및 자녀 중 일부를 게시하는 것이 적절할 수 있습니다. – netcoder
@DaveRandom : 전체적으로 스크립트는 내가 컬로 초기화하는 텍스트 스트림을 구문 분석합니다. 스트림 검색과 구문 분석/저장 프로세스를 모두 비동기식으로 결합 했으므로 스트림을 파싱하는 데 어려움을 겪고있었습니다. 즉, 네트워크를 통해 전송 된 스트림을 처리 할 때 스트림 처리에 시간이 너무 오래 걸리고 텍스트 스트림이 대기열에 백업됩니다. 스트림을받는 원본이이 백업에 제한이 있습니다.필자는 스트리밍 프로세스에서 파싱 기능을 제거하여 시간을 절약 할 수 있기를 희망했습니다. – iralls