使用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 if 想到的些问题
Mar 22 PHP
PHP中文处理 中文字符串截取(mb_substr)和获取中文字符串字数
Nov 10 PHP
php中拷贝构造函数、赋值运算符重载
Jul 25 PHP
解析thinkphp import 文件内容变量失效的问题
Jun 20 PHP
PHP常用处理静态操作类
Apr 03 PHP
5款适合PHP使用的HTML编辑器推荐
Jul 03 PHP
php插入含有特殊符号数据的处理方法
Nov 24 PHP
PHP给源代码加密的几种方法汇总(推荐)
Feb 06 PHP
php实现微信模板消息推送
Mar 30 PHP
PHP递归的三种常用方式
Feb 28 PHP
PHP信号处理机制的操作代码讲解
Apr 19 PHP
让whoops帮我们告别ThinkPHP6的异常页面
Mar 02 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使用PDO事务配合表格读取大量数据插入操作实现方法
2017/02/16 PHP
PHP简单实现解析xml为数组的方法
2018/05/02 PHP
php实现通过stomp协议连接ActiveMQ操作示例
2020/02/23 PHP
jQuery 借助插件Lavalamp实现导航条动态美化效果
2013/09/27 Javascript
jQuery通过点击行来删除HTML表格行的实现示例
2014/09/10 Javascript
javascript操作数组详解
2014/12/17 Javascript
推荐10 款 SVG 动画的 JavaScript 库
2015/03/24 Javascript
JavaScript实现表格快速变色效果代码
2015/08/19 Javascript
图解JavaScript中的this关键字
2020/05/28 Javascript
JS获取当前页面名称的简单实例
2016/08/19 Javascript
在DWR中实现直接获取一个JAVA类的返回值的两种方法
2016/12/25 Javascript
javaScript日期工具类DateUtils详解
2017/12/08 Javascript
vue.js给动态绑定的radio列表做批量编辑的方法
2018/02/28 Javascript
深入浅出理解JavaScript闭包的功能与用法
2018/08/01 Javascript
脚手架vue-cli工程webpack的基本用法详解
2018/09/29 Javascript
vue-router命名路由和编程式路由传参讲解
2019/01/19 Javascript
解决layui的input独占一行的问题
2019/09/10 Javascript
nodejs开发一个最简单的web服务器实例讲解
2020/01/02 NodeJs
JavaScript基于面向对象实现的无缝滚动轮播示例
2020/01/17 Javascript
[01:05:36]VP vs TNC Supermajor小组赛B组 BO3 第二场 6.2
2018/06/03 DOTA
实例讲解Python的函数闭包使用中应注意的问题
2016/06/20 Python
Django实战之用户认证(用户登录与注销)
2018/07/16 Python
用Python shell简化开发
2018/08/08 Python
python中join()方法介绍
2018/10/11 Python
对Python3 序列解包详解
2019/02/16 Python
python实现简单加密解密机制
2019/03/19 Python
Python可以实现栈的结构吗
2020/05/27 Python
解决阿里云邮件发送不能使用25端口问题
2020/08/07 Python
英国第一蛋白粉品牌:Myprotein
2016/09/14 全球购物
如何利用find命令查找文件
2015/02/07 面试题
大学毕业生的自我鉴定
2013/11/30 职场文书
体育教育专业自荐信范文
2013/12/20 职场文书
中班下学期幼儿评语
2014/12/30 职场文书
2015年公务员个人工作总结
2015/04/24 职场文书
今日说法观后感
2015/06/08 职场文书
飞越疯人院观后感
2015/06/09 职场文书