#### 方案一:
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"
<?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)."\n"; $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)."\n";
?>
#### 方案二
以前使用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也可以这样来实现类
class threads extends Thread
{
public $url = '';
public $options = array();
public $data; public function __construct($url, $options = array()){
$this->url = $url;
$this->options = $options;
} public function run(){
if(!empty($this->url)){
$this->data = $this->get_html($this->url, $this->options);
}
} public function get_html($url,$options = array()){
if(empty($options)){
$options[CURLOPT_RETURNTRANSFER] = true;
$options[CURLOPT_TIMEOUT] = 5;
}
$ch = curl_init($url);
curl_setopt_array($ch,$options);
$html = curl_exec($ch);
curl_close($ch);
if($html === false){
return false;
}
return $html;
}
}
PHP多线程的更多相关文章
-
Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
-
多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
-
多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
-
Java多线程
一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是一个线程. 进程:进程 ...
-
.NET基础拾遗(5)多线程开发基础
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...
-
Java多线程基础——对象及变量并发访问
在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...
-
C#多线程之线程池篇3
在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...
-
C#多线程之线程池篇2
在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...
-
C#多线程之线程池篇1
在C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点: 在线程池中调用委托 在线程池中执行异步操作 线程池和并行度 实现取消选项 使用等待句柄和超时 使用计时 ...
-
C#多线程之线程同步篇3
在上一篇C#多线程之线程同步篇2中,我们主要学习了AutoResetEvent构造.ManualResetEventSlim构造和CountdownEvent构造,在这一篇中,我们将学习Barrier ...
随机推荐
-
GNS3 桥接虚拟网卡 telnet 实验
网上很多桥接本地网卡的,一直测试不通.无奈,本人桥接vmware 虚拟网卡通! 1: 2: 3:telnet 加密实验 R1(config)#line vt R1(config)#line vty 0 ...
-
hibernate 注解 主键生成策略
一.JPA通用策略生成器 通过annotation来映射hibernate实体的,基于annotation的hibernate主键标识为@Id, 其生成规则由@GeneratedValue ...
-
求助:为什么我用360浏览器和UC浏览器打不开JAVA中的index.html文件? 一打开就显示浏览器首界页
如下图,在oracle官网下载了一个JAVA的API文档,双击index.html时打开是浏览器的首页,不知道为什么?请问怎样才能以chm文档格式显示?
-
CentOS-6.3安装配置Nginx
安装说明 系统环境:CentOS-6.3软件:nginx-1.2.6.tar.gz安装方式:源码编译安装 安装位置:/usr/local/nginx 下载地址:http://nginx.org/en/ ...
-
MySQL 5.7 重置root默认密码
http://www.cnblogs.com/jym-sunshine/p/5314101.html mysql5.7.11修改root默认密码 知道 MySQL 出了5.7了,并且网上说性能提高 ...
-
Windows Phone 8初学者开发—第8部分:理解编译和部署
原文 Windows Phone 8初学者开发—第8部分:理解编译和部署 第8部分:理解编译和部署 原文地址: http://channel9.msdn.com/Series/Windows-Phon ...
-
【linux】ubuntu下crontab无效解决方法
在Debain的docker中启用crontab,踩了一整天的坑,特地记录一下.Debain和ubuntu差不多,故算在ubuntu下面了. 1.第一个坑,安装crontab apt-get inst ...
-
post方式提交数据
<!DOCTYPE HTML><html> <head> <meta charset="utf-8" /> ...
-
代码 | 自适应大邻域搜索系列之(3) - Destroy和Repair方法代码实现解析
前言 上一篇文章中我们具体解剖了ALNS类的具体代码实现过程,不过也留下了很多大坑.接下来的文章基本都是"填坑"了,把各个模块一一展现解析给大家.不过碍于文章篇幅等原因呢,也不会每 ...
-
outlook同步异常
新装的系统,备份了outlook,还原后发现,outlook还在不停的同步服务端邮件,设置规则,禁止接收今天之前的邮件,但是outloock还是在同步,只是不接收而已,这样导致了莫名其妙的异常错误,o ...