2012-09-18 6 views
2

PHP에서 병렬 처리가 필요하지만 PHP는 확장 기능을 설치하지 않고 PHP를 지원하지 않으므로 이것을 달성하기 위해 multi_curl을 사용하고 있습니다.PHP - 병렬 처리를 위해 multi_curl을 사용하고 있습니까?

main.php - 서로 다른 $ _GET 매개 변수를 사용하여 모두 process.php 인 URL 배열을 작성합니다. 그런 다음 multi_curl을 사용하여 모두 실행합니다.

process.php - 각 스레드에 대한 처리 논리.

나는 이것이 일을 실행 가능한 방법인지 알고 싶습니다. 이것은 지체 되었습니까? 오버 헤드가 많이 발생합니까? 이 일을하는 더 합리적인 방법이 있습니까? 감사.

+0

[forking] (http://php.net/manual/en/function.pcntl-fork.php)에 대해 들어 본 적이 있습니까? – Orbling

+0

@Orbling 그건 내가 언급 한 확장 기능이야. 그러나 나는 엑스트라를 설치하고 싶지 않고, 그것에 대해 아주 좋은 것을 듣지 못했습니다. –

+0

포킹은 대부분의 시스템에서 기본 프로세스에서 다중 프로세스로 실행됩니다. PHP 프로그래머는 개념과주의 사항에 익숙하지 않기 때문에 사람들은 PHP에서 자주 사용하지 않습니다. PHP에는 많은 문제가 있지만주의 깊은 처리를 통해 프로세스를 분할하는 표준적이고 건전한 방법입니다. 컬을 사용하면 대부분의 경우 오버 헤드가 높지만 웹 서버를 통해 갈 수 있다는 이점이 있으므로 기계 등의 부하를 분산시킬 수 있습니다. – Orbling

답변

1

https://github.com/krakjoe/pthreads

스레딩 PHP 용

즐기 ...

유닉스에 설치하려면, 당신은 PHP의 스레드 안전 버전이 필요합니다. 대부분의 배포판은이 버전을 패키지하지 않으므로 직접 배포해야합니다.

수행하는 방법에 대한 간단한 설명이 너무 것 :

cd /usr/src 
wget http://php.net/get/php-5.3.17.tar.bz2/from/us.php.net/mirror 
tar -xf php-5.3.17.tar.bz2 
cd php-5.3.17/ext 
wget https://github.com/krakjoe/pthreads/tarball/master -O pthreads.tar.gz 
tar -xf pthreads.tar.gz 
mv krakjoe-pthreads* pthreads 
cd ../ 
./buildconf --force 
./configure --enable-maintainer-zts --enable-pthreads --prefix=/usr 
make 
make install 

나는 개인 위치에 고립 복사 --prefix를 구축, 그 시작하는 것 --prefix =/집 같은/mydir 또는 일부 배포판에는/usr/src/debug가 있는데 이런 종류의 일에 좋은 장소입니다. 당신은 분명히 --with-mysql 등을 추가하고 싶을 것이다.하지만 어떻게하는지는 시스템에 달려있다. (힌트, php -i | grep configure> factory.config를 사용하면 현재 PHP 설치를 저장할 수있다. 그것의 기본 라이브러리는 apt-get | yum이 설치되지 않는다고 불평하는 라이브러리가 없다는 것을 안다.

+0

재미 있습니다. 어떻게 이런 식으로 설치합니까? –

+1

당신이 유닉스에 있다고 가정하고 다운로드를 사용할 수 없다 ... 나는 그것이 올바르게 포맷 할 수 없기 때문에 나는 별도로 글을 올릴 것이다. –

0

물론 일반적인 일을 수행 할 수있는 실용적인 방법이기 때문에 그 기능이 있습니다.

언제나처럼, 악마가 세부 사항에 있습니다. 여러 동시 요청은 다른 프로세스와 경쟁하여 서버 리소스를 사용합니다. 당신은 동시성의 정도를 조절하고 싶을 것이다.

0

PHP가 합리적인 방법으로 다중 처리를 지원하지 않는다는 것을 염두에두면 multi_curl이 좋은 해결책 인 것 같습니다!

0

웹 서버에서 PHP를 실행 중이고 (다중 경로가 사용 불가능할 수 있음) 스크립트를 병렬로 실행하는 한 가지 방법은 localhost : 80에 소켓을 열고 수동으로 웹 서버에서 스크립트를 실행하도록하는 것입니다 필요. 서버 멀티 스레딩을 사용하여 병렬로 실행됩니다. 그런 다음 루프에서 모든 결과를 수집하고 모든 결과가 완료되면 (또는 선택한 시간 초과 후) 계속 진행합니다.

get_img_size.php 스크립트는 크기와 하나 개의 이미지의 정보를 검색합니다 .. 웹 페이지에서 참조되는 모든 이미지의 크기를 검색하는 스크립트에서 가져온 코드 조각입니다.

$ 소켓 []은 테스트 할 모든 이미지에 대해 하나의 소켓을 유지하는 배열입니다. 은 "스레드"작업에 대한 이동하는 동안

 foreach($metaItems['items'] as $uCnt=>$uVal) { 
      $metaItem=ContentLoader::splitOneNew($metaItems,$uCnt); 
      $AnImage=$metaItem['url']; 

      $sockets[$AnImage] = fsockopen($_SERVER['HTTP_HOST'], 80, $errno, $errstr, 30); 
      if(!$sockets[$AnImage]) { 
       echo "$errstr ($errno)<br />\n"; 
      } else { 
       $pathToRetriever=dirname($_SERVER['PHP_SELF']).'/tools/get_img_size.php?url='.rawurlencode($AnImage); 
       // echo('<div>META Retrieving '.$pathToRetriever.' on server '.$_SERVER['HTTP_HOST'].'</div>'); 
       $out = "GET $pathToRetriever HTTP/1.1\r\n"; 
       $out .= "Host: ".$_SERVER['HTTP_HOST']."\r\n"; 
       $out .= "Connection: Close\r\n\r\n"; 
       // echo($out); 
       fwrite($sockets[$AnImage], $out); 
       fflush($sockets[$AnImage]); 
       // echo("<div>Socket open for $AnImage...</div>"); 
       // flush(); 
      } 
     } 
    } else $FoundImagePaths2[]=$metaItems; // ALL of them urls belongs to us 

이 후 당신이 당신의 자신의 사업을 할 수있는, 다음, 루프, 당신은 모든 $ 소켓 []에서 읽기 및 EOF를 테스트 이동합니다.예에서, 훨씬 나중에 코드 (각 $를 Animage에 대한 루프)에 :

  if(isset($sockets[$AnImage])) { 
       if(feof($sockets[$AnImage])) { 
        if(!isset($sizes[$AnImage])) $sizes[$AnImage]=''; 
        $sizes[$AnImage].=fgets($sockets[$AnImage], 4096); 

        // echo("<div>HTML $AnImage DONE.</div>"); 
        // echo("<div>[ ".$sizes[$AnImage]." ]</div>"); 
        // flush(); 
        fclose($sockets[$AnImage]); 
        unset($sockets[$AnImage]); 

        $mysizes=ContentLoader::cleanResponse($sizes[$AnImage]); 

        // echo($sizes[$AnImage]." "); 
        // echo(ContentLoader::cleanResponse($sizes[$AnImage])); 

        if(!is_array($mysizes)) {continue;} 

        if($mysizes[0]>64 && $mysizes[1]>64 && ($mysizes[0]>128 || $mysizes[1]>128)) 
         $FoundImagePaths2[]=array('kind'=>'image','url'=>$AnImage,'ext'=>$ext,'width'=>$mysizes[0],'height'=>$mysizes[1],'mime'=>$mysizes['mime']); 

는 메모리 및 프로세스와 속도 현명 측면에서 효율적이지 않습니다,하지만 하나의 이미지가 몇 초 걸리는 경우, 20 개 이상의 이미지가있는 전체 페이지는 모두 몇 초 만에 테스트 할 수 있습니다. 그것은 결국 어떻게 든 병렬 PHP입니다.

관련 문제