Home  >  Article  >  php教程  >  php多进程几个例子

php多进程几个例子

WBOY
WBOYOriginal
2016-05-25 16:45:401501browse

php多进程这个东西先是在java中有不过现在高版本的php也支持多进程这个功能,但经过测试性能不如j(www.phprm.com)ava了希望后期有所提高了,下面我们一起来看看我整理了几个关于php多进程例子,希望能帮助你理解多线程.

php多进程的实现依赖于pcntl扩展,编译PHP的时候,可以加上"–enable-pcntl"或者也可以单独编译.

有三点需要注意:

1.子进程不在执行fork之前的代码,只是把父进程的内存状况复制一份新的,所以,关于子进程的个性化设置需要单独设置.

2.输出重定向,程序中使用echo,或造成命令行的混乱,影响分辨,可以用ob_start重定向到log文件,当然,你直接使用log是更好的办法,此实例中log文件,按照进程pid分组.

3.父进程没有代码执行,将可能提前退出,子进程可能成为孤儿进程.

demo接收:

用10个子进程来处理输出任务,任务总量是1000,然后,按照任务数平均分到十个子进程当中去,代码如下:

<?php
//输出重定向到log文件
function echo_to_log($content) {
    global $current_pid;
    $logfile = __FILE__ . $current_pid . &#39;.log&#39;;
    $fp = fopen($logfile, &#39;a+&#39;);
    fwrite($fp, $content);
    fclose($fp);
}
ob_start(&#39;echo_to_log&#39;);
//获取当前进程pid
$current_pid = getmypid();
$fork_nums = 10;
$total = 1000;
for ($i = 0; $i < $fork_nums; $i++) {
    $pid = pcntl_fork();
    //等于0时,是子进程
    if ($pid == 0) {
        $current_pid = $pid;
        do_task($i);
        //大于0时,是父进程,并且pid是产生的子进程的PID
        
    } else if ($pid > 0) {
    }
}
//任务函数
function do_task($task_num) {
    global $total;
    $start = $total / 10 * $task_num;
    $end = $total / 10 * ($task_num + 1);
    for (; $start < $end; $start++) {
        echo $task_num . " " . $start . "\n";
    }
    //子进程执行完任务以后终止,当然你可以返回主进程的代码部分做相关操作。
    exit();
}
//多进程控制的框架代码, 留着备查, 代码如下:
    declare(ticks = 1);
    function sigHandler($signal) {
        echo "a child exited\n";
    }
    pcntl_signal(SIGCHLD, sigHandler, false);
    echo "this is " . posix_getpid() . PHP_EOL;
    for ($i = 0; $i < 3; $i++) {
        $pid = pcntl_fork();
        if ($pid == - 1) {
            echo &#39;fork failed &#39; . PHP_EOL;
        } else if ($pid) {
        } else {
            $pid = posix_getpid();
            echo &#39;child &#39; . $pid . &#39; &#39; . time() . PHP_EOL;
            sleep(rand(2, 5));
            echo &#39;child &#39; . $pid . &#39; done &#39; . time() . PHP_EOL;
            exit(0);
        }
    }
    do {
        $pid = pcntl_wait($status);
        echo &#39;child quit &#39; . $pid . PHP_EOL;
    } while ($pid > 0);
    echo &#39;parent done&#39; . PHP_EOL;
?>

例子,给出一段PHP多线程、与For循环,抓取百度搜索页面的PHP代码示例,代码如下:

<?php
    class test_thread_run extends Thread {
        public $url;
        public $data;
        public function __construct($url) {
            $this->url = $url;
        }
        public function run() {
            if (($url = $this->url)) {
                $this->data = model_http_curl_get($url);
            }
        }
    }
    function model_thread_result_get($urls_array) {
        foreach ($urls_array as $key => $value) {
            $thread_array[$key] = new test_thread_run($value["url"]);
            $thread_array[$key]->start();
        }
        foreach ($thread_array as $thread_array_key => $thread_array_value) {
            while ($thread_array[$thread_array_key]->isRunning()) {
                usleep(10);
            }
            if ($thread_array[$thread_array_key]->join()) {
                $variable_data[$thread_array_key] = $thread_array[$thread_array_key]->data;
            }
        }
        return $variable_data;
    }
    function model_http_curl_get($url, $userAgent = "") {
        $userAgent = $userAgent ? $userAgent : &#39;Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)&#39;;
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_TIMEOUT, 5);
        curl_setopt($curl, CURLOPT_USERAGENT, (www . phprm . com) $userAgent);
        $result = curl_exec($curl);
        curl_close($curl);
        return $result;
    }
    for ($i = 0; $i < 100; $i++) {
        $urls_array[] = array(
            "name" => "baidu",
            "url" => "http://www.phprm.com/s?wd=" . mt_rand(10000, 20000)
        );
    }
    $t = microtime(true);
    $result = model_thread_result_get($urls_array);
    $e = microtime(true);
    echo "多线程:" . ($e - $t) . "\n";
    $t = microtime(true);
    foreach ($urls_array as $key => $value) {
        $result_new[$key] = model_http_curl_get($value["url"]);
    }
    $e = microtime(true);
    echo "For循环:" . ($e - $t) . "\n";
?>

PHP多线程类,代码如下:

<?php
    /** 
     * @title:  PHP多线程类(Thread)
     * @version: 1.0
     * @author:   < web@ >
     * @published: 2010-11-2
     *
     * PHP多线程应用示例:
     *  require_once &#39;thread.class.php&#39;;
     *  $thread = new thread();
     *  $thread->addthread(&#39;action_log&#39;,&#39;a&#39;);
     *  $thread->addthread(&#39;action_log&#39;,&#39;b&#39;);
     *  $thread->addthread(&#39;action_log&#39;,&#39;c&#39;);
     *  $thread->runthread();
     *
     *  function action_log($info) {
     *   $log = &#39;log/&#39; . microtime() . &#39;.log&#39;;
     *   $txt = $info . "rnrn" . &#39;Set in &#39; . Date(&#39;h:i:s&#39;, time()) . (double)microtime() . "rn";
     *   $fp = fopen($log, &#39;w&#39;);
     *   fwrite($fp, $txt);
     *   fclose($fp);
     *  }
     */
    class thread {
        var $hooks = array();
        var $args = array();
        function thread() {
        }
        function addthread($func) {
            $args = array_slice(func_get_args() , 1);
            $this->hooks[] = $func;
            $this->args[] = $args;
            return true;
        }
        function runthread() {
            if (isset($_GET[&#39;flag&#39;])) {
                $flag = intval($_GET[&#39;flag&#39;]);
            }
            if ($flag || $flag === 0) {
                call_user_func_array($this->hooks[$flag], $this->args[$flag]);
            } else {
                for ($i = 0, $size = count($this->hooks); $i < $size; $i++) {
                    $fp = fsockopen($_SERVER[&#39;HTTP_HOST&#39;], $_SERVER[&#39;SERVER_PORT&#39;]);
                    if ($fp) {
                        $out = "GET {$_SERVER[&#39;PHP_SELF&#39;]}?flag=$i HTTP/1.1rn";
                        $out.= "Host: {$_SERVER[&#39;HTTP_HOST&#39;]}rn";
                        $out.= "Connection: Closernrn";
                        fputs($fp, $out);
                        fclose($fp);
                    }
                }
            }
        }
    }
?>

使用方法,代码如下:

$thread = new thread(); 
$thread->addthread(&#39;func1&#39;,&#39;info1&#39;); 
$thread->addthread(&#39;func2&#39;,&#39;info2&#39;); 
$thread->addthread(&#39;func3&#39;,&#39;info3&#39;); 
$thread->runthread();

说明:addthread是添加线程函数,第一个参数是函数名,之后的参数(可选)为传递给指定函数的参数.

runthread是执行线程的函数.

在linux系统中需要配置安装一下pthreads

1、扩展的编译安装(Linux),www.phprm.com 编辑参数 --enable-maintainer-zts 是必选项,代码如下:

cd /Data/tgz/php-5.5.1 
./configure --prefix=/Data/apps/php --with-config-file-path=/Data/apps/php/etc --with-mysql=/Data/apps/mysql --with-mysqli=/Data/apps/mysql/bin/mysql_config --with-iconv-dir --with-freetype-dir=/Data/apps/libs --with-jpeg-dir=/Data/apps/libs --with-png-dir=/Data/apps/libs --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --enable-mbstring --with-mcrypt=/Data/apps/libs --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --enable-opcache --with-pdo-mysql --enable-maintainer-zts 
make clean 
make 
make install        
 
unzip pthreads-master.zip 
cd pthreads-master 
/Data/apps/php/bin/phpize 
./configure --with-php-config=/Data/apps/php/bin/php-config 
make 
make install 
vi /Data/apps/php/etc/php.ini 
添加如下代码:
extension = "pthreads.so"

PHP扩展下载:https://github.com/krakjoe/pthreads

PHP手册文档:http://php.net/manual/zh/book.pthreads.php                                        


文章网址:

随意转载^^但请附上教程地址。

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn