坑爹php多线程安装和使用
参考:http://www.manongjc.com/article/1503.html(安装)
https://segmentfault.com/q/1010000004327568?_ea=575102(问题详解)
我这边使用的是安装php7.3+pthread
- 装php前要安装下
apt-get install autoconf
- 安装php时候configure要加上–enable-maintainer-zts,然后就是常规流程php -v看版本号
- 下载pthread,扩展安装传送门,安装流程如下
cd pthreads
/usr/local/php7.3/etc/phpize
./configure --with-php-config=/usr/local/php7.3/bin/php-config
make
make install
- 然后去/usr/local/php7.3/etc下执行
cp php.ini php-cli.ini
再将extension = "pthreads.so"
添加到后面,同时执行php -m
就看到pthreads了,这边都不需要启动php-fpm后台任务,因为使用cli模式会优先读取php-cli.ini配置里的内容。
最后贴测试代码
<?php
class RequestUrl extends \Thread
{
public $url;
public $response;
public function __construct($url) {
$this->url = $url;
}
public function run() {
$this->response = $this->modelHttpCurlGet($this->url);
}
public function modelHttpCurlGet($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;
}
}
<?php
require_once('RequestUrl.php');
function model_thread_result_get($urlsArray)
{
foreach ($urlsArray as $key => $value)
{
$threadArray[$key] = new RequestUrl($value["url"]);
$threadArray[$key]->start();
}
foreach ($threadArray as $thread_array_key => $thread_array_value)
{
while($threadArray[$thread_array_key]->isRunning())
{
usleep(10);
}
if($threadArray[$thread_array_key]->join())
{
$variableData[$thread_array_key] = $threadArray[$thread_array_key]->data;
}
}
return $variableData;
}
for ($i=0; $i < 100; $i++)
{
$urls[] = [
"name" => "baidu",
"url" => "http://www.baidu.com/s?wd=".mt_rand(10000,20000)
];
}
// 多线程测试
$startTimeThread = microtime(true);
$result = model_thread_result_get($urls);
$endTimeThread = microtime(true);
echo "多线程:".($endTimeThread-$startTimeThread)."\n";
// for循环测试
$t = microtime(true);
foreach ($urls as $key => $value)
{
$requestUrl = new RequestUrl('');
$result_new[$key] = $requestUrl->modelHttpCurlGet($value["url"]);
}
$e = microtime(true);
echo "For循环:".($e-$t)."\n";
?>
本地执行php Test.php
显示
或者如果想看下线程数
可以将链接数改成100000个,然后跑,再看top
发现php跑的进程id为60895,再执行pstree -p 6089 | wc -l
查看该进程下的线程数量
—分割线–
多进程,线程测试保留代码
php代码测试:
//多进程
<?php
// 选择模式 1swoole 2 单进程
$select = $argv[1];
$s_time = time();
echo '开始时间:'.date('H:i:s',$s_time).PHP_EOL;
//模拟地址
$curl=[
'https://blog.csdn.net/feiwutudou',
'https://wiki.swoole.com/wiki/page/215.html',
'http://fanyi.baidu.com/?aldtype=16047#en/zh/manager',
'https://www.jianshu.com/p/462013f18177',
'https://blog.csdn.net/liuxingjiaoyuC/article/details/109485413?utm_medium=distribute.pc_feed.none-task-blog-personrec_tag-3.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-personrec_tag-3.nonecase&request_id=5fa70989f4522c71cec0d07f',
'https://blog.csdn.net/marksinoberg/article/details/77816991',
'https://blog.csdn.net/liuxingjiaoyuC/article/details/108753405',
'https://blog.csdn.net/liuxingjiaoyuC/article/details/108579764',
'https://blog.csdn.net/liuxingjiaoyuC/article/details/109333744',
'https://www.cnblogs.com/52fhy/p/8901815.html',
];
if($select == 1){
swooleProcess($curl);
}elseif($select == 2){
phpCommon($curl);
}else{
var_dump('选择模式不符合要求');
return;
}
//单进程模式
function phpCommon($curl)
{
foreach ($curl as $v) {
echo curldeta($v);
}
}
// swoole多进程
function swooleProcess($curl)
{
$work_number = count($curl);//进程数
$worker=[];
//创建进程
for ($i=0; $i < $work_number; $i++) {
//创建多进程
$pro=new swoole_process(function(swoole_process $work) use($i,$curl){
//获取html文件
$content=curldeta($curl[$i]);
//写入管道
$work->write($content.PHP_EOL);
},true);
$pro_id=$pro->start();
$worker[$pro_id]=$pro;
}
//读取管道内容
foreach ($worker as $v) {
echo $v->read().PHP_EOL;
}
//进程回收
swoole_process::wait();
}
//模拟爬虫
function curldeta($curl_arr)
{
echo $curl_arr.PHP_EOL;
file_get_contents($curl_arr);
}
$e_time = time();
echo '结束时间:'.date('H:i:s',$e_time).PHP_EOL;
echo '所用时间:'.($e_time-$s_time).'秒'.PHP_EOL;
// 多线程
<?php
class RequestUrl extends \Thread
{
public $url;
public $response;
public function __construct($url) {
$this->url = $url;
}
public function run() {
$this->response = $this->modelHttpCurlGet($this->url);
}
public function modelHttpCurlGet($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;
}
}
<?php
require_once('RequestUrl.php');
function model_thread_result_get($urlsArray)
{
foreach ($urlsArray as $key => $value)
{
$threadArray[$key] = new RequestUrl($value["url"]);
$threadArray[$key]->start();
}
foreach ($threadArray as $thread_array_key => $thread_array_value)
{
while($threadArray[$thread_array_key]->isRunning())
{
usleep(10);// 延迟代码执行若干微秒
}
if($threadArray[$thread_array_key]->join())
{
$variableData[$thread_array_key] = $threadArray[$thread_array_key]->data;
}
}
return $variableData;
}
for ($i=0; $i < 100000; $i++)
{
$urls[] = [
"name" => "baidu",
"url" => "http://www.baidu.com/s?wd=".mt_rand(10000,20000)
];
}
// 多线程测试
$startTimeThread = microtime(true);
$result = model_thread_result_get($urls);
$endTimeThread = microtime(true);
echo "多线程:".($endTimeThread-$startTimeThread)."\n";
die;
// for循环测试
$t = microtime(true);
foreach ($urls as $key => $value)
{
$requestUrl = new RequestUrl('');
$result_new[$key] = $requestUrl->modelHttpCurlGet($value["url"]);
}
$e = microtime(true);
echo "For循环:".($e-$t)."\n";
?>