zoukankan      html  css  js  c++  java
  • PHP多线程

    #### 方案一:

    PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程。多线程在处理重复性的循环任务,能够大大缩短程序执行时间。
    我之前的文章中说过,大多数网站的性能瓶颈不在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

    vi /Data/apps/php/etc/php.ini

    添加:
    extension = "pthreads.so"

     1 <?php  
     2   class test_thread_run extends Thread   
     3   {  
     4       public $url;  
     5       public $data;  
     6   
     7       public function __construct($url)  
     8       {  
     9           $this->url = $url;  
    10       }  
    11   
    12       public function run()  
    13       {  
    14           if(($url = $this->url))  
    15           {  
    16               $this->data = model_http_curl_get($url);  
    17           }  
    18       }  
    19   }  
    20   
    21   function model_thread_result_get($urls_array)   
    22   {  
    23       foreach ($urls_array as $key => $value)   
    24       {  
    25           $thread_array[$key] = new test_thread_run($value["url"]);  
    26           $thread_array[$key]->start();  
    27       }  
    28   
    29       foreach ($thread_array as $thread_array_key => $thread_array_value)   
    30       {  
    31           while($thread_array[$thread_array_key]->isRunning())  
    32           {  
    33               usleep(10);  
    34           }  
    35           if($thread_array[$thread_array_key]->join())  
    36           {  
    37               $variable_data[$thread_array_key] = $thread_array[$thread_array_key]->data;  
    38           }  
    39       }  
    40       return $variable_data;  
    41   }  
    42   
    43   function model_http_curl_get($url,$userAgent="")   
    44   {  
    45       $userAgent = $userAgent ? $userAgent : 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)';   
    46       $curl = curl_init();  
    47       curl_setopt($curl, CURLOPT_URL, $url);  
    48       curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);  
    49       curl_setopt($curl, CURLOPT_TIMEOUT, 5);  
    50       curl_setopt($curl, CURLOPT_USERAGENT, $userAgent);  
    51       $result = curl_exec($curl);  
    52       curl_close($curl);  
    53       return $result;  
    54   }  
    55   
    56   for ($i=0; $i < 100; $i++)   
    57   {   
    58       $urls_array[] = array("name" => "baidu", "url" => "http://www.baidu.com/s?wd=".mt_rand(10000,20000));  
    59   }  
    60   
    61   $t = microtime(true);  
    62   $result = model_thread_result_get($urls_array);  
    63   $e = microtime(true);  
    64   echo "多线程:".($e-$t)."
    ";  
    65   
    66   $t = microtime(true);  
    67   foreach ($urls_array as $key => $value)   
    68   {  
    69       $result_new[$key] = model_http_curl_get($value["url"]);  
    70   }  
    71   $e = microtime(true);  
    72   echo "For循环:".($e-$t)."
    ";  
    73 ?>  

    #### 方案二

    以前使用curl的多线程并不是真正的多线程,只是一种模拟的多线程,现在使用pthreads来实现真正意义上的多线程。

    下载:

      windows下:

        http://windows.php.net/downloads/pecl/releases/pthreads/0.0.45/

      mac、unix、linux下:

        https://github.com/krakjoe/pthreads

    安装方式:

      windows下:

        解压得到pthreadVC2.dll和php_pthreads.dll文件,把vc2文件放到php.exe同级目录,把php_pthreads.dll放到扩展目录下。

        修改php.ini文件 添加extension=php_pthreads.dll

        修改Apache配置文件httpd.conf 添加LoadFile "yourpath/php/pthreadVC2.dll"

      mac、unix、linux下:

        具体可参考宴哥的博客http://blog.s135.com/pthreads/

    调用方式:

      具体的用法也可以参考宴哥的博客http://blog.s135.com/pthreads/

      结合以前的get_html也可以这样来实现类

     1 class threads extends Thread
     2 {
     3     public $url = '';
     4     public $options = array();
     5     public $data;
     6 
     7     public function __construct($url, $options = array()){
     8         $this->url = $url;
     9         $this->options = $options;
    10     }
    11 
    12     public function run(){
    13         if(!empty($this->url)){
    14             $this->data = $this->get_html($this->url, $this->options);
    15         }
    16     }
    17 
    18     public function get_html($url,$options = array()){
    19         if(empty($options)){
    20             $options[CURLOPT_RETURNTRANSFER] = true;
    21             $options[CURLOPT_TIMEOUT] = 5;
    22         }
    23         $ch = curl_init($url);
    24         curl_setopt_array($ch,$options);
    25         $html = curl_exec($ch);
    26         curl_close($ch);
    27         if($html === false){
    28             return false;
    29         }
    30         return $html;
    31     }
    32 }
  • 相关阅读:
    Eos开发——构造查询条件
    随记
    Spring的三种通过XML实现DataSource注入方式
    事务处理
    Spring AOP实例——异常处理和记录程序执行时间
    输出日志实例改成用Spring的AOP来实现
    用ProxyFactoryBean创建AOP代理
    Spring的通知(Advice)
    Spring的3种切入点PointCut实现
    学习AOP之JAVA的代理机制
  • 原文地址:https://www.cnblogs.com/ahwu/p/3525804.html
Copyright © 2011-2022 走看看