PHP多进程运行利器-signfork v1.0.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;
                }
        }
}

?>

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/67199.html