2011-12-24 67 views
1

我已经创建了一个脚本,可以从互联网上下载非常大的文件。通过HTTP下载文件时减少CPU使用量

的东西很简单:

<?php 
$source = fsockopen(…); // http 
$destination = fopen(…,'wb'); // file 
while (!feof($source)) 
{ 
    fwrite($destination,fread($source,4096)); 
} 
fclose($source); 
fclose($destination); 
?> 

它的伟大工程,但这个剧本我的服务器上使用100%的CPU下载大约每秒10 MB的时候。这是正常的吗?

这是一款Intel Xeon四核酷睿X3323 @ 2.50 GHz。

P.S.实际上它有点复杂,因为我的脚本首先读取HTTP标头,但没关系。

回答

1

在大多数情况下,您不应该首先使用套接字实现HTTP。相反,使用curl或者干脆fopen封装,就像

copy("http://example.net/", "example.html"); 

但是,如果你坚持做自己的插座处理,请注意,如果没有什么阅读fread会返回一个空字符串。如果您的套接字处于非阻塞模式,fread将立即返回''。您可以拨打电话socket_set_block将插座重新置于阻塞模式:

<?php 
$source = fsockopen(…); // http 
$destination = fopen(…,'wb'); // file 
socket_set_block($source); 
stream_copy_to_stream($source, $destination); 
fclose($source); 
fclose($destination); 
+0

默认情况下套接字不会被阻塞,除非OP明确地使其成为非阻塞的? – Alnitak 2011-12-24 12:41:50

+0

@Alnitak Yup。然而,OP遗漏了很多代码,并且在那里可能有一个'socket_set_nonblock'。如果套接字将被阻塞,则循环不会导致100%的CPU。 – phihag 2011-12-24 12:48:14

0

不,使用100%的CPU只是这样做是不正常的。

您是否考虑过使用stream-copy-to-stream()来处理从一个文件流到另一个文件流的副本?

+0

@phihag oops - thanks - corrected。 – Alnitak 2011-12-24 12:43:33