lang/php

PHP 병렬처리

C/H 2017. 3. 17. 08:30

pcntl_fork

pcntl_fork 는 cgi 실행에서만 가능하다. apache 모듈에서는 지원하지 않는다.

$var = 'one';

$pid = pcntl_fork(); // pcntl_fork 는 cgi 실행에서만 가능하다. apache 모듈에서는 지원하지 않는다.
if ($pid === -1) {
    exit; // fork 실패
} elseif ($pid === 0) {

   /*
    * 기존 변수는 두 프로세스 모두에 있다.
    * 변경 사항은 다른 프로세스에 영향을 미치지 않는다.
    */
    echo $var;
    $var = 'two';

} else { // parent 쓰레드
    echo $var; // one
    $var = 'three'; // 자식 프로세스에 영향을 미치지 않는다.

    pcntl_wait($status); // 부모가 자식 프로세스보다 오래 지속되는지 확인해야 한다.
}

popen

popen() 으로 하위 프로세스를 시작.

popen을 호출하면 상위 스크립트는 하위 프로세스가 완료 될 때까지 기다리지 않고 실행을 다시 시작한다.
stream_get_contents가 호출 될 때까지 하위 프로세스 만 대기한다.

stream_get_contents가 부모의 실행을 차단하도록하려면 stream_set_blocking ($ child1, 0)을 추가한다.
stream_set_blocking 하지 않은 스트림이 완료되기 전에 stream_get_contents를 실행하면 부분 응답만 받는다.
stream_set_timeout : 데이터 스트림 수신 대기시간의 타임 아웃 설정
socket_set_timeout : 소켓 연결중 데이터 송수신 없이 대기하는 타임아웃 설정

전체 응답을 읽으려면 feof ($ child)가 true를 반환 할 때까지 자식 스트림의 모든 stream_get_contents를 연결해야 한다.
그래야 부모가 자식 프로세스가 완료된것을 알 수 있다.

$child1 = popen('php child.php', 'r');
$child2 = popen('php child.php', 'r');
$child3 = popen('php child.php', 'r');
//$child1 = fopen('http://'.$_SERVER['HTTP_HOST'].'/child.php', 'r');
//$child2 = fopen('http://'.$_SERVER['HTTP_HOST'].'/child.php', 'r');
//$child3 = fopen('http://'.$_SERVER['HTTP_HOST'].'/child.php', 'r');

stream_set_blocking($child1, FALSE); // 타이아웃 해제로 완료될때까지 기다린다
stream_set_blocking($child2, FALSE);
stream_set_blocking($child3, FALSE);
$res1 = stream_get_contents($child1);
$res2 = stream_get_contents($child2);
$res3 = stream_get_contents($child3);


반응형

'lang > php' 카테고리의 다른 글

Requests for PHP  (0) 2017.05.23
CI 2.6 에서 redis 캐시드라이브  (0) 2017.03.20
centos php-fpm session.save_handler redis setting  (0) 2017.03.02
Centos7 Nginx+php7+php-fpm  (0) 2017.02.21
php7.1 mcrypt_get_iv_size Error  (0) 2017.02.17