2011-12-24 63 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