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文檔 點擊打開鏈接