使用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 相关文章推荐
用文本文件制作留言板提示(下)
Oct 09 PHP
php更改目录及子目录下所有的文件后缀的代码
Sep 24 PHP
apache+php完美解决301重定向的两种方法
Jun 08 PHP
关于PHP的curl开启问题探讨
Apr 08 PHP
php的慢速日志引起的Mysql错误问题分析
May 13 PHP
PHP生成唯一订单号
Jul 05 PHP
PHP实现生成唯一会员卡号
Aug 24 PHP
php中namespace use用法实例分析
Jan 22 PHP
Joomla使用Apache重写模式的方法
May 04 PHP
php如何执行非缓冲查询API
Jul 22 PHP
ThinkPHP实现生成和校验验证码功能
Apr 28 PHP
PHP实现的杨辉三角求解算法分析
Mar 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
文件上传的实现
2006/10/09 PHP
php中处理模拟rewrite 效果
2006/12/09 PHP
PHP在线生成二维码(google api)的实现代码详解
2013/06/04 PHP
javascript实现上传图片并预览的效果实现代码
2011/04/11 Javascript
基于jQuery替换table中的内容并显示进度条的代码
2011/08/02 Javascript
js 通用javascript函数库整理
2011/08/14 Javascript
js函数调用常用方法详解
2012/12/03 Javascript
屏蔽网页右键复制和ctrl+c复制的js代码
2013/01/04 Javascript
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
jquery中.add()的使用分析
2013/04/26 Javascript
用jquery生成二级菜单的实例代码
2013/06/24 Javascript
JavaScript和CSS通过expression实现Table居中显示
2013/06/28 Javascript
js实现刷新iframe的方法汇总
2015/04/27 Javascript
14款经典网页图片和文字特效的jQuery插件-前端开发必备
2015/08/25 Javascript
简介EasyUI datagrid editor combogrid搜索框的实现
2016/04/01 Javascript
微信小程序签到功能
2018/10/31 Javascript
python网络编程学习笔记(二):socket建立网络客户端
2014/06/09 Python
python通过pil为png图片填充上背景颜色的方法
2015/03/17 Python
python中list常用操作实例详解
2015/06/03 Python
Python实现向服务器请求压缩数据及解压缩数据的方法示例
2017/06/09 Python
Python安装图文教程 Pycharm安装教程
2018/03/27 Python
对numpy.append()里的axis的用法详解
2018/06/28 Python
使用tensorflow实现线性svm
2018/09/07 Python
对Python中画图时候的线类型详解
2019/07/07 Python
Python生成器实现简单&quot;生产者消费者&quot;模型代码实例
2020/03/27 Python
Python实现转换图片背景颜色代码
2020/04/30 Python
python中threading和queue库实现多线程编程
2021/02/06 Python
在线购买澳大利亚设计师手拿包和奢华晚装手袋:Olga Berg
2019/03/20 全球购物
Python文件操作的面试题
2013/06/22 面试题
初中生学习生活的自我评价
2013/11/20 职场文书
奥巴马的演讲稿
2014/05/15 职场文书
母亲节寄语大全
2015/02/27 职场文书
2015年高校教师个人工作总结
2015/05/25 职场文书
网络舆情信息简报
2015/07/21 职场文书
Spring boot应用启动后首次访问很慢的解决方案
2021/06/23 Java/Android
MySQL 外连接语法之 OUTER JOIN
2022/04/09 MySQL