使用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 相关文章推荐
如何将数据从文本导入到mysql
Oct 09 PHP
模拟flock实现文件锁定
Feb 14 PHP
mysql From_unixtime及UNIX_TIMESTAMP及DATE_FORMAT日期函数
Mar 21 PHP
PHP Stream_*系列函数
Aug 01 PHP
PHP和Mysqlweb应用开发核心技术-第1部分 Php基础-2 php语言介绍
Jul 03 PHP
显示程序执行时间php函数代码
Aug 29 PHP
PHP取余函数介绍MOD(x,y)与x%y
May 15 PHP
Linux下创建nginx脚本-start、stop、reload…
Aug 03 PHP
smarty表格换行实例
Dec 15 PHP
php随机获取金山词霸每日一句的方法
Jul 09 PHP
PHP API接口必备之输出json格式数据示例代码
Jun 27 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
Sep 16 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中使用TCPDF生成PDF文档实例
2014/07/01 PHP
PHPWind9.0手动屏蔽验证码解决后台关闭验证码但是依然显示的问题
2016/08/12 PHP
DEDE实现转跳属性文档在模板上调用出转跳地址
2016/11/04 PHP
PHP实现RSA签名生成订单功能【支付宝示例】
2017/06/06 PHP
PHP数组去重的更快实现方式分析
2018/05/09 PHP
基于ThinkPHP删除目录及目录文件函数
2020/10/28 PHP
随机显示经典句子或诗歌的javascript脚本
2007/08/04 Javascript
javascript 动态调整图片尺寸实现代码
2009/12/28 Javascript
JQuery自适应IFrame高度(支持嵌套 兼容IE,ff,safafi,chrome)
2011/03/28 Javascript
加载 Javascript 最佳实践
2011/10/30 Javascript
jQuery 关于伪类选择符的使用说明
2013/04/24 Javascript
jQuery让控件左右移动的三种实现方法
2013/09/08 Javascript
jQuery中noconflict函数的实现原理分解
2015/02/03 Javascript
vue.js中$watch的用法示例
2016/10/04 Javascript
Auto.js自动收取自己和好友蚂蚁森林能量脚本
2018/06/28 Javascript
JavaScript实现拖拽功能
2020/02/11 Javascript
[03:18]DOTA2亚洲邀请赛小组赛第一日 RECAP赛事回顾
2015/01/30 DOTA
Python使用Mechanize模块编写爬虫的要点解析
2016/03/31 Python
在阿里云服务器上配置CentOS+Nginx+Python+Flask环境
2016/06/18 Python
Python下的Softmax回归函数的实现方法(推荐)
2017/01/26 Python
Python实现希尔排序算法的原理与用法实例分析
2017/11/23 Python
python去除扩展名的实例讲解
2018/04/23 Python
解决Python 中英文混输格式对齐的问题
2018/07/16 Python
浅述python中深浅拷贝原理
2018/09/18 Python
python实现基于信息增益的决策树归纳
2018/12/18 Python
Python IDLE或shell中切换路径的操作
2020/03/09 Python
Python闭包与装饰器原理及实例解析
2020/04/30 Python
解决numpy矩阵相减出现的负值自动转正值的问题
2020/06/03 Python
Python第三方包PrettyTable安装及用法解析
2020/07/08 Python
Python实现AES加密,解密的两种方法
2020/10/03 Python
Python类型转换的魔术方法详解
2020/12/23 Python
德国户外装备、登山运动和攀岩商店:tapir store
2020/02/12 全球购物
机电职业生涯规划书范文
2014/03/08 职场文书
校园联欢晚会主持词
2014/03/17 职场文书
升职自荐信范文
2015/03/27 职场文书
小学教师党员承诺书
2015/04/27 职场文书