PHP多進程編程

來源:互聯網
上載者:User

PHP本身不支援多線程,多進程支援的也不是特別好,網上找到一份多進程代碼(http://jasonyu.cn/html/2010/294.html),寫了一個測試程式簡單測了一下,可以運行,但是離上線還差得很遠。

<?php/** * Project: Signfork: php多線程庫 * File: Signfork.class.php */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;        }    }}?>

測試程式如下:

<?phprequire_once(dirname(__FILE__) . '/Signfork.class.php');class ExecObj{    public function __fork($param){        return getmypid();    }    }echo getmypid()."\n";$signfork = new Signfork();$result = $signfork->run(new ExecObj(),5);foreach ($result as $key=>$val){    echo $key." ".$val."\n";}?>

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.