代码改变世界

PHP中的并行处理(简)

2011-11-09 16:55  AnyKoro  阅读(1849)  评论(0编辑  收藏  举报

针对多核的cpu泛滥的今天,如何使用好这些CPU资源成了重要的话题。于是异步和并行便开始了大行其道。在PHP中也有异步或并行编程的概念。接下来让我们看具体的例子。

并行处理                                                                              

现在我们需要跑两个任务,分别为job1.php和job2.php

job1.php的代码如下:

$jobname = 'job1';
set_time_limit(0);
$secs = 30;

while ($secs) {
echo 'current job is'.$jobname,'::',$secs,"\n";
flush(); @ob_flush(); ## make sure that all output is sent in real-time
$secs -= 1;
$t = time();
sleep(1); // pause
}

job2.php的代码只是在$jobname处为job2,其他和job1都一样。
有了任务,我们自然还需要执行的php文件,为run.php,代码如下:

#
#
run.php
#
function JobStartAsync($server, $url, $port=80,$conn_timeout=30, $rw_timeout=86400)
{
$errno = '';
$errstr = '';

set_time_limit(0);

$fp = fsockopen($server, $port, $errno, $errstr, $conn_timeout);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
return false;
}
$out = "GET $url HTTP/1.1\r\n";
$out .= "Host: $server\r\n";
$out .= "Connection: Close\r\n\r\n";

stream_set_blocking($fp, false);
stream_set_timeout($fp, $rw_timeout);
fwrite($fp, $out);

return $fp;
}

// returns false if HTTP disconnect (EOF), or a string (could be empty string) if still connected
function JobPollAsync(&$fp)
{
if ($fp === false) return false;

if (feof($fp)) {
fclose($fp);
$fp = false;
return false;
}

return fread($fp, 10000);
}

###########################################################################################


if (1) { /* SAMPLE USAGE BELOW */

$fp1 = JobStartAsync('localhost','/jobs/job1.php');
$fp2 = JobStartAsync('localhost','/jobs/job2.php');


while (true) {
sleep(1);

$r1 = JobPollAsync($fp1);
$r2 = JobPollAsync($fp2);

if ($r1 === false && $r2 === false) break;

echo "<b>r1 = </b>$r1<br>";
echo "<b>r2 = </b>$r2<hr>";
flush(); @ob_flush();
}

echo "<h3>Jobs Complete</h3>";
}

 就此完成,输出如下

r1 = HTTP/1.1 200 OK
Date: Wed, 03 Sep 2008 07:20:20 GMT
Server: Apache/2.2.4 (Unix) mod_ssl/2.2.4 OpenSSL/0.9.8d
X-Powered-By: Zend Core/2.5.0 PHP/5.2.5
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

7 current job is job1::30

r2 = HTTP/1.1 200 OK
Date: Wed, 03 Sep 2008 07:20:20 GMT
Server: Apache/2.2.4 (Unix) mod_ssl/2.2.4 OpenSSL/0.9.8d
X-Powered-By: Zend Core/2.5.0 PHP/5.2.5
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

7 current job is job2::30
----
r1 = 7 current job is job1::29

r2 = 7 current job is job2::29
----
r1 = 7 current job is job1::28

r2 = 7 current job is job2::28

----

 此处采用了fsockopen进行了实现,但是有时候,为了更高效,我们可以使用popen完成相同的功能。只是传入的command需要时运行php的command,比如php /xxx/xxx/xxx/job/job1.php (这对linux的情况)