使用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的面向对象编程
Oct 09 PHP
php空间不支持socket但支持curl时recaptcha的用法
Nov 07 PHP
浅析PHP原理之变量(Variables inside PHP)
Aug 09 PHP
php集成环境xampp中apache无法启动问题解决方案
Nov 18 PHP
php读取文件内容到数组的方法
Mar 16 PHP
PHP Cookie学习笔记
Aug 23 PHP
Yii CFileCache 获取不到值的原因分析
Feb 08 PHP
解决PHP上传非标准格式的图片pjpeg失败的方法
Mar 12 PHP
php实现用户注册密码的crypt加密
Jun 08 PHP
PHP xpath()函数讲解
Feb 11 PHP
thinkphp5框架调用其它控制器方法 实现自定义跳转界面功能示例
Jul 03 PHP
yii2.0框架使用 beforeAction 防非法登陆的方法分析
Sep 11 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
学习php设计模式 php实现建造者模式
2015/12/07 PHP
Yii2组件之多图上传插件FileInput的详细使用教程
2016/06/20 PHP
Laravel框架验证码类用法实例分析
2019/09/11 PHP
初窥JQuery(二) 事件机制(1)
2010/11/25 Javascript
同一页面多个商品倒计时JS 基于面向对象的javascript
2012/02/16 Javascript
纯js实现仿QQ邮箱弹出确认框
2015/04/29 Javascript
动态加载js、css的实例代码
2016/05/26 Javascript
全面了解JS中的匿名函数
2016/06/29 Javascript
Javascript将JSON日期格式化
2016/08/23 Javascript
详解Angular2组件之间如何通信
2017/06/22 Javascript
JavaScript实现二维坐标点排序效果
2017/07/18 Javascript
javascript中new Array()和var arr=[]用法区别
2017/12/01 Javascript
学习Vue组件实例
2018/04/28 Javascript
微信小程序 子级页面返回父级并把子级参数带回父级实现方法
2019/08/22 Javascript
js实现全选和全不选
2020/07/28 Javascript
Vue filter 过滤器、以及在table中的使用介绍
2020/09/07 Javascript
vue.js watch经常失效的场景与解决方案
2021/01/07 Vue.js
Python中使用ConfigParser解析ini配置文件实例
2014/08/30 Python
浅谈Python数据类型之间的转换
2016/06/08 Python
Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容
2018/02/23 Python
python 获得任意路径下的文件及其根目录的方法
2019/02/16 Python
python算法题 链表反转详解
2019/07/02 Python
python使用 request 发送表单数据操作示例
2019/09/25 Python
python可视化 matplotlib画图使用colorbar工具自定义颜色
2020/12/07 Python
canvas与html5实现视频截图功能示例
2016/12/15 HTML / CSS
猎人靴英国官网:Hunter Boots
2017/02/02 全球购物
主要的Ajax框架都有什么
2013/11/14 面试题
高级护理专业大学生求职信
2013/10/24 职场文书
幼儿园数学教学反思
2014/02/02 职场文书
组织鉴定材料
2014/06/02 职场文书
老龄工作先进事迹
2014/08/15 职场文书
乡镇群众路线专项整治方案
2014/11/03 职场文书
2014年惩防体系建设工作总结
2014/12/01 职场文书
结婚典礼致辞
2015/07/28 职场文书
MySQL去除重叠时间求时间差和的实现
2021/08/23 MySQL
java版 简单三子棋游戏
2022/05/04 Java/Android