使用pthreads实现真正的PHP多线程(需PHP5.3以上版本)


Posted in PHP onMay 05, 2014

我之前的文章中说过,大多数网站的性能瓶颈不在PHP服务器上,因为它可以简单地通过横向增加服务器或CPU核数来轻松应对(对于各种云主机,增加VPS或CPU核数就更方便了,直接以备份镜像增加VPS,连操作系统、环境都不用安装配置),而是在于MySQL数据库。

如果用 MySQL 数据库,一条联合查询的SQL,也许就可以处理完业务逻辑,但是,遇到大量并发请求,就歇菜了。

如果用 NoSQL 数据库,也许需要十次查询,才能处理完同样地业务逻辑,但每次查询都比 MySQL 要快,十次循环NoSQL查询也许比一次MySQL联合查询更快,应对几万次/秒的查询完全没问题。

如果加上PHP多线程,通过十个线程同时查询NoSQL,返回结果汇总输出,速度就要更快了。我们实际的APP产品中,调用一个通过用户喜好实时推荐商品的PHP接口,PHP需要对BigSea NoSQL数据库发起500~1000次查询,来实时算出用户的个性喜好商品数据,PHP多线程的作用非常明显。

PHP扩展下载:https://github.com/krakjoe/pthreads
PHP手册文档:http://php.net/manual/zh/book.pthreads.php

1、扩展的编译安装(Linux),编译参数 --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

php.ini中添加:

vi /Data/apps/php/etc/php.ini
extension = "pthreads.so"

给出一段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, $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)."
";
  $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)."
";
?>
PHP 相关文章推荐
PHP中MD5函数使用实例代码
Jun 07 PHP
利用discuz实现PHP大文件上传应用实例代码
Nov 14 PHP
使用php计算排列组合的方法
Nov 13 PHP
php判断手机访问还是电脑访问示例分享
Jan 20 PHP
PHP实现的比较完善的购物车类
Dec 02 PHP
thinkPHP中分页用法实例分析
Dec 26 PHP
yii去掉必填项中星号的方法
Dec 28 PHP
Laravel中基于Artisan View扩展包创建及删除应用视图文件的方法
Oct 08 PHP
php curl中gzip的压缩性能测试实例分析
Nov 08 PHP
OAuth认证协议中的HMACSHA1加密算法(实例)
Oct 25 PHP
php 将json格式数据转换成数组的方法
Aug 21 PHP
laravel5使用freetds连接sql server的方法
Dec 07 PHP
PHP FATAL ERROR: CALL TO UNDEFINED FUNCTION BCMUL()解决办法
May 04 #PHP
PHP图片裁剪函数(保持图像不变形)
May 04 #PHP
PHP_NETWORK_GETADDRESSES: GETADDRINFO FAILED问题解决办法
May 04 #PHP
PHP按行读取文件时删除换行符的3种方法
May 04 #PHP
Linux中用PHP判断程序运行状态的2个方法
May 04 #PHP
PHP CURL获取返回值的方法
May 04 #PHP
PHP判断远程图片是否存在的几种方法
May 04 #PHP
You might like
Zend Framework页面缓存实例
2014/06/25 PHP
PHP格式化显示时间date()函数代码
2018/10/03 PHP
js一组验证函数
2008/12/20 Javascript
JQuery index()方法使用代码
2010/06/02 Javascript
24款非常有用的 jQuery 插件分享
2011/04/06 Javascript
javascript中的delete使用详解
2013/04/11 Javascript
自动设置iframe大小的jQuery代码
2013/09/11 Javascript
Javascript中Array.prototype.map()详解
2014/10/22 Javascript
node.js中的http.response.write方法使用说明
2014/12/14 Javascript
javascript实现淘宝幻灯片广告展示效果
2015/04/27 Javascript
jquery实现树形菜单完整代码
2015/12/29 Javascript
Angularjs根据json文件动态生成路由状态的实现方法
2017/04/17 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
2018/05/21 jQuery
layui table设置前台过滤转义等方法
2018/08/17 Javascript
JavaScript静态作用域和动态作用域实例详解
2019/06/17 Javascript
在layui框架中select下拉框监听更改事件的例子
2019/09/20 Javascript
vue实现购物车加减
2020/05/30 Javascript
Python模块学习 re 正则表达式
2011/05/19 Python
python下MySQLdb用法实例分析
2015/06/08 Python
使用python遍历指定城市的一周气温
2017/03/31 Python
Python读取和处理文件后缀为.sqlite的数据文件(实例讲解)
2017/06/27 Python
python自动发送邮件脚本
2018/06/20 Python
Python通过paramiko远程下载Linux服务器上的文件实例
2018/12/27 Python
详解opencv Python特征检测及K-最近邻匹配
2019/01/21 Python
Python控制台实现交互式环境执行
2020/06/09 Python
Python实现迪杰斯特拉算法并生成最短路径的示例代码
2020/12/01 Python
美国百年历史早餐食品供应商:Wolferman’s
2017/01/18 全球购物
携程英文网站:Trip.com
2017/02/07 全球购物
中东奢侈品市场:Coveti
2019/05/12 全球购物
Dr. Martens马汀博士法国官网:马丁靴鼻祖
2020/01/15 全球购物
售后服务科岗位职责范文
2013/11/13 职场文书
精彩自我鉴定
2014/01/16 职场文书
学校三八妇女节活动情况总结
2014/03/09 职场文书
县政协领导班子群众路线教育实践活动四风问题整改方案
2014/10/26 职场文书
幼儿园大班教学反思
2016/03/02 职场文书
互联网的下一个风口:新的独角兽将诞生
2019/08/02 职场文书