일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- WebView
- UML
- 안드로이드
- chart.js
- javascript
- 설치
- dovecot
- 우분투
- 안드로이드 gcm
- C#
- 폼메일
- not working
- Android
- 안드로이드 푸쉬
- C# IO
- soundpool
- android 효과음
- xe
- PHP
- curl
- 자바스크립트
- 안드로이드 푸시
- Mail Server
- roundcube
- php 시큐어코딩
- html5
- FCM
- php 취약점
- mysql
- 자동 생성
- Today
- Total
그러냐
curl_multi를 이용한 병렬처리 본문
첨부화일은 REST용 병렬처리 샘플 소스이다.
(http://gonzalo123.com/2010/02/06/building-a-rest-client-with-asynchronous-calls-using-php-and-curl/)
PHP에서 시간 많이 걸리는 처리를 병렬로 실행하여 고속화 할수 있다.
PHP에는 pcntl_fork라는 프로세스를 포크할수 있는 함수가 있지만 CGI모드에서만 유효해
일반적으로 PHP를 Apache모듈로 동작시키는 환경에서는 사용할수 없다.
그외에는 system함수등을 사용하여 시스템콜로 백그라운드에서 처리시키는 경우이다.
-
system('php -f test.php > /dev/null &');
curl_multi를 사용해서 병렬처리
PHP5에서 curl_multi_*라는 함수군을 사용할수 있게 되었다.
curl함수는 대상을 실행시켜(URL등으로) 출력되는 결과를 리다이렉트등의 페이지 이동없이 얻을수 있다.
PHP5에서는 이러한 처리는 병렬로 가능하게 하는 curl_multi시리즈가 추가 되었다.
이것을 이용해 API에 동시에 복수의 리퀘스트를 던져 병렬처리가 되도록 해보자
-
<?php
-
header('Content-type:text/html; charset=UTF-8');
-
-
//동시 처리시킬 URL
-
$url_list = array(
-
);
-
-
$time = time();
-
-
//실행
-
$res = fetch_multi_url($url_list);
-
-
//결과 출력
-
echo '실행 결과:<pre>';
-
print_r($res);
-
echo '</pre>';
-
-
//실행 시간
-
echo '--<br />time:'.(time() - $time).' sec';
-
-
/**
-
* fetch_multi_url
-
*
-
* @param array $url_list
-
* @param int $timeout
-
* @return array
-
*/
-
function fetch_multi_url( array $url_list, $timeout=0 ) {
-
$mh = curl_multi_init();
-
-
foreach ($url_list as $i => $url) {
-
$conn[$i] = curl_init($url);
-
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);
-
curl_setopt($conn[$i],CURLOPT_FAILONERROR,1);
-
curl_setopt($conn[$i],CURLOPT_FOLLOWLOCATION,1);
-
curl_setopt($conn[$i],CURLOPT_MAXREDIRS,3);
-
-
//SSL증명서 무시
-
curl_setopt($conn[$i],CURLOPT_SSL_VERIFYPEER,false);
-
curl_setopt($conn[$i],CURLOPT_SSL_VERIFYHOST,false);
-
-
//타임아웃
-
if ($timeout){
-
curl_setopt($conn[$i],CURLOPT_TIMEOUT,$timeout);
-
}
-
-
curl_multi_add_handle($mh,$conn[$i]);
-
}
-
-
$active = null;
-
do {
-
$mrc = curl_multi_exec($mh,$active);
-
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
-
-
while ($active and $mrc == CURLM_OK) {
-
if (curl_multi_select($mh) != -1) {
-
do {
-
$mrc = curl_multi_exec($mh,$active);
-
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
-
}
-
}
-
-
if ($mrc != CURLM_OK) {
-
echo '읽기 에러가 발생:'.$mrc;
-
}
-
-
//결과 취득
-
$res = array();
-
foreach ($url_list as $i => $url) {
-
if (($err = curl_error($conn[$i])) == '') {
-
$res[$i] = curl_multi_getcontent($conn[$i]);
-
} else {
-
echo '취득실패:'.$url_list[$i].'<br />';
-
}
-
curl_multi_remove_handle($mh,$conn[$i]);
-
curl_close($conn[$i]);
-
}
-
curl_multi_close($mh);
-
-
return $res;
-
}
-
<?php
-
sleep(5);
-
echo 'pid='.$_GET['pid'];
개당 5초간 sleep
이 sleep.php를 4번 실행한다면
5초 x 4회 = 20초정도 걸릴것이다.
-
Array
-
(
-
[0] => pid=1
-
[1] => pid=2
-
[2] => pid=3
-
[3] => pid=4
-
)
-
-
--
-
time:5 sec
5초만에 실행되었다.
DNS해석처리를 병렬로 실행
실제의 IP어드레스를 호스트명으로 바꾸는 처리를 병렬로 해보았다.
중복하지 않는 IP1,000개에 대하여 php의 gethostbyaddr함수를 실행
결과
-----------------------------------
순차:124초
병력(10개):33초
-----------------------------------
시간이 많이 걸리는 때는 set_time_limit의 설정을..
ignore_user_abort를 사용하면 백그라운드 처리도 가능하다.
'php' 카테고리의 다른 글
php continue Warning 뜨는 경우 (0) | 2020.11.05 |
---|---|
[PHP]CSV파일 다운로드, 한글 깨짐, UTF-8 BOM (0) | 2019.12.30 |
[PHPEXCEL] phpexcel 사용법 (0) | 2019.10.24 |
네이버 스마트 에디터 이미지 리사이즈 (3) | 2019.04.03 |
PHPExcel 시트추가 add sheet (0) | 2019.02.13 |