关键词:
php中可以通过CURL处理HTTP请求,其中curl_init()是单线程模式,如果需要对事务处理走多线程模式,那么就需要用到curl_multi_init()函数。
本案例用来测试大并发的情况下 curl_multi_init() 到底比 curl_init() 快多少。
话不多少,直接上代码:
<?php class Http /** * https 发起post请求 * @param string $url url信息 * @param mixed $data 参数信息[$data = ‘"a":1,"b":2‘ or $data = array("a" => 1,"b" => 2)] * @param int $timeOut 超时设置 * @param string $proxyHost 代理host * @param int $proxyPort 代理端口 * @return string */ public static function post($url, $data = null, $timeOut = 20, $proxyHost = null, $proxyPort = null) try if (strlen($url) < 1) return null; $ch = curl_init(); // 设置url curl_setopt($ch, CURLOPT_URL, $url); if (false == empty($data)) curl_setopt($ch, CURLOPT_POST, 1); if (is_array($data) && count($data) > 0) curl_setopt($ch, CURLOPT_POST, count($data)); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 如果成功只将结果返回,不自动输出返回的内容 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // user-agent curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"); // 超时 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeOut); // 使用代理 if (strlen($proxyHost) > 0 && strlen($proxyPort) > 0) // 代理认证模式 curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC); // 代理服务器地址 curl_setopt($ch, CURLOPT_PROXY, $proxyHost); // 代理服务器端口 curl_setopt($ch, CURLOPT_PROXYPORT, $proxyPort); // 使用http代理模式 curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); // 执行 $out = curl_exec($ch); // 关闭 curl_close($ch); return $out; catch (Exception $e) return null; /** * https 发起post多发请求 * @param array $nodes url和参数信息。 * $nodes = [ * [0] = > [ * ‘url‘ => ‘http://www.baidu.com‘, * ‘data‘ => ‘"a":1,"b":2‘ * ], * [1] = > [ * ‘url‘ => ‘http://www.baidu.com‘, * ‘data‘ => null * ] * .... * ]; * @param int $timeOut 超时设置 * @return array */ public static function postMulti($nodes, $timeOut = 5) try if (false == is_array($nodes)) return array(); $mh = curl_multi_init(); $curlArray = array(); foreach ($nodes as $key => $info) if (false == is_array($info)) continue; if (false == isset($info[‘url‘])) continue; $ch = curl_init(); // 设置url $url = $info[‘url‘]; curl_setopt($ch, CURLOPT_URL, $url); $data = isset($info[‘data‘]) ? $info[‘data‘] : null; if (false == empty($data)) curl_setopt($ch, CURLOPT_POST, 1); // array if (is_array($data) && count($data) > 0) curl_setopt($ch, CURLOPT_POST, count($data)); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 如果成功只将结果返回,不自动输出返回的内容 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // user-agent curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"); // 超时 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeOut); $curlArray[$key] = $ch; curl_multi_add_handle($mh, $curlArray[$key]); $running = NULL; do usleep(10000); curl_multi_exec($mh, $running); while ($running > 0); $res = array(); foreach ($nodes as $key => $info) $res[$key] = curl_multi_getcontent($curlArray[$key]); foreach ($nodes as $key => $info) curl_multi_remove_handle($mh, $curlArray[$key]); curl_multi_close($mh); return $res; catch (Exception $e) return array(); $count = 10; //2.1 循环调用Http::post() 100次 $url = ‘https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=abcdasdfasdfasdfasdfasdfasdfasdfasdfasdf‘; $startTime = microtime(true); for ($i = 1; $i <= $count; $i++) $res = Http::post($url); $endTime = microtime(true); echo $endTime - $startTime; echo "\n"; //2.2 调用Http::postMulti()一次发100个url $url = ‘https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=abcdasdfasdfasdfasdfasdfasdfasdfasdfasdf‘; $nodes = array(); for ($i = 1; $i <= $count; $i++) $info = array(); $info[‘url‘] = $url; $nodes[] = $info; $startTime = microtime(true); $res = Http::postMulti($nodes); $endTime = microtime(true); echo $endTime - $startTime; echo "\n"; ?>
运行结果:
* 当$count=10的情况下,耗时分别为:
3.4119510650635 0.44486904144287
curl_multi_init() 比 curl_init() 快了8倍。
* 当 $count=100的情况下,耗时分别为:
34.190015077591 1.9350771903992
curl_multi_init() 比 curl_init() 快了17倍。
php利用curl实现多进程下载文件类(代码片段)
...处理方法,开启多进程,实现批量下载文件。主要方法:curl_multi_init:返回一个新cURL批处理句柄curl_multi_add_handle:向curl批处 查看详情
如何在 PHP 应用程序中使用多线程
】如何在PHP应用程序中使用多线程【英文标题】:HowcanoneusemultithreadinginPHPapplications【发布时间】:2010-09-0909:49:28【问题描述】:是否有一种在PHP中实现多线程模型的现实方法,无论是真实的还是只是模拟它。前段时间有人建议... 查看详情
用php的curl实现并发请求远程文件(抓取远程网页)
PHP的curl功能确实强大了。里面有个curl_multi_init功能,就是批量处理任务。可以利用此,实现多进程同步抓取多条记录,优化普通的网页抓取程序。一个简单的抓取函数:functionhttp_get_multi($urls){$count=count($urls);$data=[];$chs=[];//... 查看详情
phpcli是守护进程的吗
...注:windows和linux下都支持php_cli模式PHP-cli应用场景:1.多线程应用这方面的好处,引用鸟哥的话:优点:1.使用多进程,子进程结束以后,内核会负责回收资源2.使用多进程,子进程异常退出不会导致整个进程Thread退出.父进程还有机会... 查看详情
php实现多线程编程(代码片段)
来源:http://www.cnblogs.com/zhenbianshu/p/7978835.html多线程线程首先说下线程:线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个... 查看详情
我可以利用多线程 PHP 进行慢速 sql 查询吗
】我可以利用多线程PHP进行慢速sql查询吗【英文标题】:CanIleverageMulti-ThreadedPHPforslowsqlqueries【发布时间】:2021-06-1318:04:44【问题描述】:我的任务是链接两个不同API的id,链接将基于名称完成,因此使用通配符的搜索有点慢。例... 查看详情
jQuery POST 多线程延迟
】jQueryPOST多线程延迟【英文标题】:jQueryPOSTmultithreadeddelays【发布时间】:2017-10-0501:06:39【问题描述】:我正在使用PHP代码中的多线程POST请求。由于这些请求可能需要很长时间,我决定对这些POST请求进行多线程处理,以通过使... 查看详情
多线程中join方法的含义
...用:调用这个方法的时候,主进程会在这里停住,等待该线程进行完毕再继续往下执行。如:不使用join的情况:<?phpclassJoinextendsThread{publicfunctionrun(){sleep(3);echo__FUNCTION__.PHP_EOL;}}$join=newJoin();$join->start();echo‘justatest‘.PHP_EOL; 查看详情
多线程的使用
1为什么使用多线程 1.1发挥多核cpu的优势 单核CPU上的多线程是假的多线程,同一时间处理器只会处理一段逻辑,只是在多个线程之间进行快速切换 多核CPU才能实现真正的多线程,同时处理多个逻辑,充分利... 查看详情
python多进程和多线程的使用(代码片段)
...参数args和kwargs5.进程之间不共享全局变量6.守护进程7.多线程7.1线程介绍7.2多线程实现方式8.线程的无序执行9.守护线程10.线程之间共享全局变量11.线程共享全局变量出现的问题12.线程同步13.互斥锁14.解释一下互斥锁产生的死锁问... 查看详情
多线程开发+多线程使用共享数据-17
进程:运行着的程序线程:每个进程里面至少包含一个线程,线程是操作系统创建的,用来控制代码执行的数据结构,线程就像代码的执行许可证单线程程序,主线程的入口就是代码的开头主线程顺序往下执行,直到所有的... 查看详情
多线程2-使用多线程(代码片段)
此章包含: 1、线程的实现方式、2、实例变量与线程安全3、线程常用的几个api4、停止线程5、暂停线程6、yield方法7、线程的优先级、8、守护线程。1、线程的常见实现方式有两种。继承Thread或实现Runable接口。代码如下://继... 查看详情
多线程和多进程的区别
...考技术A一般运行一个程序称为一个进程。进程可以创建线程,也可以创建进程。多线程和多进程的区别:线程是由进程管理的,线程之间、线程和父进程(创建线程的进程)之间可以共享内存变量(需要使用策略的)。进程之间一般... 查看详情
java多线程原理及thread类的使用
一、进程与线程的区别1.进程是应用程序在内存总分配的空间。(正在运行中的程序)2.线程是进程中负责程序执行的执行单元、执行路径。3.一个进程中至少有一个线程在负责进程的运行。4.一个进程中有多个线程在运行的程序... 查看详情
多线程线程同步
一,线程的同步有以下方法 1,使用synchronized实现同步方法; 2,使用非依赖属性实现同步; 3,在同步代码块中使用条件; 4,使用锁实现同步; 5,使用读写同步数据访问; 6,修改锁的公平性; ... 查看详情
java多线程的基本使用(代码片段)
文章目录1.多线程的概念2.线程的实现方式2.1继承Thread类实现多线程2.2实现Runnable接口实现多线程2.3实现Callable的多线程1.多线程的概念在程序执行的时候,即使没有开启多线程,Java后台也有多个线程在运行,最基本的... 查看详情
多线程介绍以及线程池的使用和业务场景
多线程介绍、列举线程池和业务场景:1).什么是多线程1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务进程->车间,线程->车间工人多线程技术可以提高程序的执行效率比如同时开启3条线程分别下... 查看详情
开发源码--php实现多线程
...时任务和自动任务有可能会发生并发,所以不得不考虑多线程。我在网上也找了很多资料貌似不符合我的需求,最后结合前辈的智慧和自己的专研,还是实现了; publicfunctiontesta(){ $id=$ 查看详情