进程是资源分配的最小单位,线程是CPU调度的最小单位
1. 多线程并发:通过cURL并发请求
1.1 通过curl_multi实现
PHP cURL所有函数列表
并发中用的curl_multi_*相关函数
1.2 PHP curl_multi 实现并发请求步骤
- 调用 curl_multi_init,初始化一个批处理handle
- 循环调用 curl_multi_add_handle,往1中的批处理handle 添加curl_init来的子handle
- 持续调用 curl_multi_exec,直到所有子handle执行完毕。
- 根据需要循环调用 curl_multi_getcontent 获取结果
- 调用 curl_multi_remove_handle,并为每个字handle调用curl_close
- 调用 curl_multi_close
1.3 PHP curl_multi 实现代码
<?php
function multiGetRequest(array $urls):array {
$mh = curl_multi_init();
foreach ($urls as $i => $url) { $connect[$i] = curl_init($url); curl_setopt($connect[$i], CURLOPT_HEADER, 0); curl_setopt($connect[$i], CURLOPT_CONNECTTIMEOUT, 60); curl_setopt($connect[$i], CURLOPT_RETURNTRANSFER, true); curl_multi_add_handle($mh, $connect[$i]); }
do { curl_multi_exec($mh, $active); } while ($active);
$return=[]; foreach ($urls as $i => $url) { $return[] = curl_multi_getcontent($connect[$i]);
} foreach ($urls as $i => $url) { curl_multi_remove_handle($mh, $connect[$i]); curl_close($connect[$i]); }
curl_multi_close($mh); return $return; }
|
2. 多进程并发:通过swoole_process实现
查看文档
2.1 示例代码
<?php
$start_time = microtime(true); $urls = [ 'http://liuqinghui.dev.lywf.me/test/libin/ttt', 'http://liuqinghui.dev.lywf.me/test/libin/ttt', 'http://liuqinghui.dev.lywf.me/test/libin/ttt', 'http://liuqinghui.dev.lywf.me/test/libin/ttt', 'http://liuqinghui.dev.lywf.me/test/libin/ttt', ];
foreach ($urls as $url) {
$process = new swoole_process("my_process", true);
$process->start();
$process->write($url);
$process_list[] = $process;
}
foreach ($process_list as $process){ echo $rec = $process->read(); }
while ($ret = swoole_process::wait()) { $pid = $ret['pid']; echo PHP_EOL . "Worker Exit, PID=" . $pid . PHP_EOL; }
function my_process(swoole_process $worker) { sleep(1); $url = $worker->read(); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); $return = curl_exec($ch); curl_close($ch); $worker->write($return); } $end_time = microtime(true); echo sprintf("use time:%.3f s\n", $end_time - $start_time);
|
3. 多进程和多线程的区别?如何选择
3.1 不同的维度的对比
| 对比维度 |
多进程 |
多线程 |
总结 |
| 数据共享、同步 |
数据共享复杂,需要用IPC; 数据是分开的,同步简单 |
因共享进程数据,数据共享简单。 但也因此导致同步复杂 |
各有优势 |
| 内存、CPU |
占用内存多,切换复杂。 CPU利用率低 |
占用内存少,切换简单,CPU利用率高 |
线程占优 |
| 创建销毁、切换 |
创建销毁、切换复杂,速度慢 |
创建销毁、切换简单,速度很快 |
线程占优 |
| 编程、调试 |
编程简单,调试简单 |
编程复杂,调试复杂 |
进程占优 |
| 可靠性 |
进程间不会互相影响 |
一个线程挂掉将导致整个进程挂掉 |
进程占优 |
| 分布式 |
适应于多核、多机分布式; 扩展到多台机器比较简单 |
适应于多核分布式 |
进程占优 |
如何选择?