- 论坛徽章:
- 0
|
使用PHP真正的多进程运行模式(真正利用多核CPU),适用于数据采集、邮件群发、数据源更新、tcp服务器等环节。
下载地址 http://code.google.com/p/signfork/downloads/list
运行条件:*NUX环境、 编译时需要 --enable-pcntl posix扩展
以下是主程序文件:
- <?php
- /**
- * Project: Signfork: php多线程库
- * File: Signfork.class.php
- *
- * @link [url]http://code.google.com/p/signfork/[/url]
- * @author lajabs <hittyo at gmail dot com> QQ:124321697
- * @version 1.0.0 2009/8/4
- */
- class Signfork
- {
- /**
- * 设置子进程通信文件所在目录
- * @var string
- */
- private $tmp_path='/tmp/';
- /**
- * Signfork引擎主启动方法
- * 1、判断$arg类型,类型为数组时将值传递给每个子进程;类型为数值型时,代表要创建的进程数.
- * @param object $obj 执行对象
- * @param string|array $arg 用于对象中的__fork方法所执行的参数
- * 如:$arg,自动分解为:$obj->__fork($arg[0])、$obj->__fork($arg[1])...
- * @return array 返回 array(子进程序列=>子进程执行结果);
- */
- public function run($obj,$arg=1)
- {
- if(!method_exists($obj,'__fork'))
- {
- exit("Method '__fork' not found!");
- }
- if(is_array($arg))
- {
- $i=0;
- foreach($arg as $key=>$val)
- {
- $spawns[$i]=$key;
- $i++;
- $this->spawn($obj,$key,$val);
- }
- $spawns['total']=$i;
- }
- elseif($spawns=intval($arg))
- {
- for($i = 0; $i < $spawns; $i++)
- {
- $this->spawn($obj,$i);
- }
- }
- else
- {
- exit('Bad argument!');
- }
- if($i>1000) exit('Too many spawns!');
- return $this->request($spawns);
- }
- /**
- * Signfork主进程控制方法
- * 1、$tmpfile 判断子进程文件是否存在,存在则子进程执行完毕,并读取内容
- * 2、$data收集子进程运行结果及数据,并用于最终返回
- * 3、删除子进程文件
- * 4、轮询一次0.03秒,直到所有子进程执行完毕,清理子进程资源
- * @param string|array $arg 用于对应每个子进程的ID
- * @return array 返回 array([子进程序列]=>[子进程执行结果]);
- */
- private function request($spawns)
- {
- $data=array();
- $i=is_array($spawns)?$spawns['total']:$spawns;
- for($ids = 0; $ids<$i; $ids++)
- {
- while(!($cid=pcntl_waitpid(-1, $status, WNOHANG)))usleep(30000);
- $tmpfile=$this->tmp_path.'sfpid_'.$cid;
- $data[$spawns['total']?$spawns[$ids]:$ids]=file_get_contents($tmpfile);
- unlink($tmpfile);
- }
- return $data;
- }
- /**
- * Signfork子进程执行方法
- * 1、pcntl_fork 生成子进程
- * 2、file_put_contents 将'$obj->__fork($val)'的执行结果存入特定序列命名的文本
- * 3、posix_kill杀死当前进程
- * @param object $obj 待执行的对象
- * @param object $i 子进程的序列ID,以便于返回对应每个子进程数据
- * @param object $param 用于输入对象$obj方法'__fork'执行参数
- */
- private function spawn($obj,$i,$param=null)
- {
- if(pcntl_fork()===0)
- {
- $cid=getmypid();
- file_put_contents($this->tmp_path.'sfpid_'.$cid,$obj->__fork($param));
- posix_kill($cid, SIGTERM);
- exit;
- }
- }
- }
- ?>
复制代码
[ 本帖最后由 bs 于 2009-8-26 01:45 编辑 ] |
|