2012-04-17 2 views
3

내 문제는 이것입니다. 디스크에있는 파일에 대한 액세스 시간을 단축 할 수 있도록 프로세스를 포크합니다. 이 파일의 데이터를 로컬 데스크의 tmp 파일에 저장합니다. 이상적으로 모든 프로세스가 끝나면 tmp 파일에 액세스하여 그 데이터를 배열로 가져와야합니다. 그런 다음 더 이상 필요하지 않은 tmp 파일의 연결을 끊습니다. 내 문제는 pcntl_wait()이 모든 자식 프로세스가 최종 작업 집합으로 이동하기 전에 완료 될 때까지 기다리지 않는 것처럼 보일 것입니다. 그래서 임의의 프로세스가 끝나기 전에 그 파일의 링크를 끊습니다.모든 pids가 PHP에서 종료되기를 기다리는 중

모든 프로세스가 정상적으로 종료되고 데이터에 액세스 할 때까지 기다릴 수있는 확실한 방법을 찾지 못하는 것 같습니다.

$numChild  = 0;  
    $maxChild  = 20; // max number of forked processes. 

    // get a list of "availableCabs" 

    foreach ($availableCabs as $cab) { 

      // fork the process 
      $pids[$numChild] = pcntl_fork(); 

      if (!$pids[$numChild]) { 

        // do some work  
        exit(0); 

      } else { 

        $numChild++; 
        if ($numChild == $maxChild) { 

          pcntl_wait($status); 
          $numChild--; 

        } 

      } // end fork 

    } 

    // Below is where things fall apart. I need to be able to print the complete serialized data. but several child processes don't actually exit before i unlink the file. 

    $dataFile = fopen($pid, 'r'); 

    while(($values = fgetcsv($dataFile,',')) !== FALSE) { 
      $fvalues[] = $values; 
    } 

    print serialize($fvalues); 

    fclose($dataFile); 
    unlink($file);  

내가 실제로하는 일에 관해서는 많은 코드를 남겨두고 있습니다.

+1

당신은'$ PID를에 매일 PID를 통해 반복 시도 할 수 있습니다 [$ numChild]'및 http://php.net/pcntl_waitpid 각 (pcntl_wait 다른 어느) . –

+0

그래서'foreach()'루프 밖에서 테스트하고 있습니까? 업데이 트에 대한 –

답변

5

코드를 재구성하여 프로세스를 생성하는 루프와 프로세스가 완료 될 때까지 대기하는 루프가 두 개 있습니다. 또한 현재 사용중인 간단한 하위 계산 방식이 아닌 특정 프로세스 ID를 확인하려면 pcntl_waitpid()을 사용해야합니다. 이 같은

뭔가 :

<?php 

    $maxChildren = 20; // Max number of forked processes 
    $pids = array();  // Child process tracking array 

    // Get a list of "availableCabs" 

    foreach ($availableCabs as $cab) { 

    // Limit the number of child processes 
    // If $maxChildren or more processes exist, wait until one exits 
    if (count($pids) >= $maxChildren) { 
     $pid = pcntl_waitpid(-1, $status); 
     unset($pids[$pid]); // Remove PID that exited from the list 
    } 

    // Fork the process 
    $pid = pcntl_fork(); 

    if ($pid) { // Parent 

     if ($pid < 0) { 
     // Unable to fork process, handle error here 
     continue; 
     } else { 
     // Add child PID to tracker array 
     // Use PID as key for easy use of unset() 
     $pids[$pid] = $pid; 
     } 

    } else { // Child 

     // If you aren't doing this already, consider using include() here - it 
     // will keep the code in the parent script more readable and separate 
     // the logic for the parent and children 

     exit(0); 

    } 

    } 

    // Now wait for the child processes to exit. This approach may seem overly 
    // simple, but because of the way it works it will have the effect of 
    // waiting until the last process exits and pretty much no longer 
    foreach ($pids as $pid) { 
    pcntl_waitpid($pid, $status); 
    unset($pids[$pid]); 
    } 

    // Now the parent process can do it's cleanup of the results 
+0

주셔서 감사합니다. 많은 것을 배워서 포크로 만들기에 익숙하다. 내가 이걸주고 가서 내가 어디에 있는지 보게. –

+0

이 잘 작동했습니다. 도와 주셔서 감사합니다. –

+0

걱정할 필요가 없습니다. :-) – DaveRandom

관련 문제