作者: 溪水清澈
据测试, 可以接收到完整的信息.
最初添加到 $mh的连接最少为2, 多了看机器
目前缺点, CPU使用率太高了.
不过速度到是挺快的.
我给a2.php添加延迟 usleep( 50000 );
这段程序只用了3秒, 就完成1000个连接了.
另一个测试程序, 使用curl_exec系统函数, 需要55秒.
<?php
set_time_limit( 0 );
$st = microtime( 1 );
// 一共要访问这些地址
$urls = array();
$n = 1000;
for( $i = 0; $i < $n; $i ++ )
{
// 这是我的虚拟主机, a2.php文件中只有一行
// echo 'in a2.php ', $_GET[ 'n' ];
$urls[] = "http://s.com/a2.php?n=$i";
}
$options = array(
CURLOPT_RETURNTRANSFER => 1, // 返回内容不直接显示
);
// 初始化批处理
$mh = curl_multi_init();
// 先添加 x 个会话资源到批处理中
// 最少是添加2个, 多了看机器
for( $i = 0; $i < 100; $i ++ )
{
// 初始化一个会话资源
$ch = curl_init( $urls[ $i ] );
// 设置
curl_setopt_array( $ch, $options );
// 添加会话到批处理中
curl_multi_add_handle( $mh, $ch );
}
// 记录当前应该添加的urls的索引
$curI = $i;
// 记录已收到多少条数据
$recvCount = 0;
do
{
$mrc = curl_multi_exec( $mh, $active );
// 获取当前连接的信息, $msgq是当前队列中还有多少条消息
$info = curl_multi_info_read( $mh, $msgq );
if( $info )
{
echo "active: $active, mrc: $mrc<br />";
// 为真, 则收到信息了
echo '收到消息, 编号: ', ++ $recvCount, '<br />';
echo '<p>', str_repeat( ' ', 16), '消息队列剩余: ', $msgq, '</p>';
// 当前这条消息的资源
$handle = $info[ 'handle' ];
// 读取收到的内容
$recv[] = curl_multi_getcontent( $handle );
// 移除本资源
curl_multi_remove_handle( $mh, $handle );
// 关闭资源
curl_close( $handle );
// 再添加一个新的, 如果还有urls未处理, 则添加
if( $curI < $n )
{
$url = $urls[ $curI ];
echo '<p>', str_repeat( ' ', 32 ), '添加: ', $url, '</p>';
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
curl_multi_add_handle( $mh, $ch );
$curI ++;
}
echo '<script>document.body.scrollTop += 1000;</script>';
ob_flush();
flush();
}
// 判断是否还有会话未结束?
// $active 还有 多少个会话
// $mrc 未发生错误
// $msgq 还有多少个消息未读
} while( $active && $mrc == CURLM_OK || $msgq > 0 );
// 显示收到的条数
echo '一共收到: ', count( $recv ), ' 条<br />';
$et = microtime( 1 );
echo '一共用时: ', $et - $st;
// 以下显示收到的回信
// 自然排序
//natsort( $recv );
// 显示收到的数据
//echo '<pre>';
//print_r( $recv );
//echo '</pre>';