PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程。多线程在处理重复性的循环任务,能够大大缩短程序执行时间。
pthreads扩展需要php是以线程安全模式安装,而一般的linux下php是以非线程安全模式安装,所以可能就需要重新安装php
1、获取原来php的安装配置,php -i | grep configure
Configure Command => './configure' '--prefix=/usr/local/php' '--with-config-file-path=/usr/local/php/etc' '--enable-fpm' '--with-fpm-user=www' '--with-fpm-group=www' '--with-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-pdo-mysql=mysqlnd' '--with-iconv-dir' '--with-freetype-dir' '--with-jpeg-dir' '--with-png-dir' '--with-zlib' '--with-libxml-dir=/usr' '--enable-xml' '--disable-rpath' '--enable-magic-quotes' '--enable-safe-mode' '--enable-bcmath' '--enable-shmop' '--enable-sysvsem' '--enable-inline-optimization' '--with-curl' '--enable-mbregex' '--enable-mbstring' '--with-mcrypt' '--enable-ftp' '--with-gd' '--enable-gd-native-ttf' '--with-openssl' '--with-mhash' '--enable-pcntl' '--enable-sockets' '--with-xmlrpc' '--enable-zip' '--enable-soap' '--without-pear' '--with-gettext' '--disable-fileinfo'
2、到php的源代码下重新编译安装,添加configure参数--enable-maintainer-zts,zts就是Zend Thread Safety,编译安装。
3、下载pthreads 代码 点击打开链接,我下载了2.0.10,
因为从3.0开始pthreads源码的pthreads.h文件里会要求加载下面2个,在php源码里没找到这俩个文件,所以还是先用老版本安装
#include <Zend/zend_inheritance.h>
#include <Zend/zend_smart_str.h>
4、pthreads安装
unzip pthreads-2.0.10.zip
cd pthreads-2.0.10
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install
5、 然后在php.ini中添加pthreads.so
ZendGuardLoader.so6、重启php,会有can't load /usr/local/zend/ZendGuardLoader.so 差不多这样的提示,因为ZendGuardLoader不能在thread safety模式下运行。
不会有太大影响,可以先忽略。
输入phpinfo()或者 php -m 可以看到pthreads已经正常安装;
6、网上一个使用例子
<?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, $userAgent);
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
for ($i=0; $i < 100; $i++)
{
$urls_array[] = array("name" => "baidu", "url" => "http://www.baidu.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";
?>
说明下,运行Thread->start() 方法会在独立线程中执行 run 方法,其他使用方法可以参照pthreads文档 点击打开链接