a#mailto:777777@163.com
c#mailto:888888@163.com
c work done # 1504499850
a work done # 1504499850
b#mailto:999999@163.com
b work done # 1504499852
通过输出结果可以得到
1. a、b、c三个进程同时开始执行,时间戳为1504499844
2. a和c同时结束执行,分别处理了3条记录,时间戳为1504499850,耗时6s
3. b最后结束执行,处理了4条记录,时间戳为1504499852,耗时8s
master-worker模式
我们模拟Web服务器处理http请求的操作,对于每个请求创建一个进程,用于处理请求内容。
class WebServer { private $list; public function __construct() { $this->list = []; } public function worker($request){ $pid = pcntl_fork(); if($pid == -1){ return false; } if($pid > 0){ return $pid; } if($pid == 0){ $time = $request[0]; $method = $request[1]; $start = time(); echo getmypid()."\t start ".$method."\tat".$start.PHP_EOL; sleep($time); $end = time(); $cost = $end-$start; echo getmypid()."\t stop \t".$method."\tat:".$end."\tcost:".$cost.PHP_EOL; exit(0); } } public function master($requests){ $start = time(); echo "All request handle stop at ".$start.PHP_EOL; foreach ($requests as $request){ $pid = $this->worker($request); if(!$pid){ echo 'handle fail!'.PHP_EOL; return; } array_push($this->list,$pid); } while(count($this->list)>0){ foreach ($this->list as $k=>$pid){ $res = pcntl_waitpid($pid,$status,WNOHANG); if($res == -1 || $res > 0){ unset($this->list[$k]); } } usleep(100); } $end = time(); $cost = $end - $start; echo "All request handle stop at ".$end."\t cost:".$cost.PHP_EOL; } } $requests = [ [1,'GET index.php'], [2,'GET index.php'], [3,'GET index.php'], [4,'GET index.php'], [5,'GET index.php'], [6,'GET index.php'] ]; $server = new WebServer(); $server->master($requests);
输出结果:
All request handle stop at 1504513048
18945 start GET index.php at1504513048
18944 start GET index.php at1504513048
18946 start GET index.php at1504513048
18947 start GET index.php at1504513048
18948 start GET index.php at1504513048
18949 start GET index.php at1504513048
18944 stop GET index.php at:1504513049 cost:1
18945 stop GET index.php at:1504513050 cost:2
18946 stop GET index.php at:1504513051 cost:3