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 . '.log'; $fp = fopen($logfile, 'a+'); fwrite($fp, $content); fclose($fp); } ob_start('echo_to_log'); //获取当前进程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 'fork failed ' . PHP_EOL; } else if ($pid) { } else { $pid = posix_getpid(); echo 'child ' . $pid . ' ' . time() . PHP_EOL; sleep(rand(2, 5)); echo 'child ' . $pid . ' done ' . time() . PHP_EOL; exit(0); } } do { $pid = pcntl_wait($status); echo 'child quit ' . $pid . PHP_EOL; } while ($pid > 0); echo 'parent done' . 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 : 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)'; $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 'thread.class.php'; * $thread = new thread(); * $thread->addthread('action_log','a'); * $thread->addthread('action_log','b'); * $thread->addthread('action_log','c'); * $thread->runthread(); * * function action_log($info) { * $log = 'log/' . microtime() . '.log'; * $txt = $info . "rnrn" . 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn"; * $fp = fopen($log, 'w'); * 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['flag'])) { $flag = intval($_GET['flag']); } 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['HTTP_HOST'], $_SERVER['SERVER_PORT']); if ($fp) { $out = "GET {$_SERVER['PHP_SELF']}?flag=$i HTTP/1.1rn"; $out.= "Host: {$_SERVER['HTTP_HOST']}rn"; $out.= "Connection: Closernrn"; fputs($fp, $out); fclose($fp); } } } } } ?>
使用方法,代码如下:
$thread = new thread(); $thread->addthread('func1','info1'); $thread->addthread('func2','info2'); $thread->addthread('func3','info3'); $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
文章网址:
随意转载^^但请附上教程地址。