2011-06-06 84 views
2

我正試圖在php中爲我的任務實現某種'多處理'。任務是檢查我們網絡中每個設備的狀態。php exec如何計算時間?

因此,我決定使用循環exec,它的工作原理。但我不知道它是否工作正常與否:

$command = "php scan_part.php $i > null &"; 
exec($command); 

這就要求scan_part.php多次我需要的,但問題是:我怎麼能計算出所需的所有我scan_part.php的時間是執行?

請幫助我,我卡住了!

+0

多線程和多處理都是有效的方法來並行(具有不同的優點和缺點),但是是不同的。你應該真的叫你'多處理'而不是'多線程',因爲PHP絕對不支持線程。 – zneak 2011-06-06 13:49:51

+0

謝謝,作了更正。關於這個問題的任何想法? – k102 2011-06-06 13:51:02

回答

6

使用proc_open,而不是推出exec你的腳本。 Proc_open讓你等待,直到通過proc_close完成一個過程,該過程一直等到程序結束。

$starttime = microtime(true); 
$processes = array(); 
// stdin, stdout, stderr- take no input, save no output 
$descriptors = array(
    0 => array("file", "/dev/null", 'r'), 
    1 => array("file", "/dev/null", 'w'), 
    2 => array("file", "/dev/null", 'w')); 

while ($your_condition) 
{ 
    $command = "php scan_part.php $i"; // no pipe redirection, no background mark 
    $processes[] = proc_open($command, $descriptors, $pipes); 
} 

// proc_close will block until the program terminates or will return immediately 
// if the program has already terminated 
foreach ($processes as $process) 
    proc_close($process); 
$endtime = microtime(true); 

$delta = $endtime - $starttime; 
+0

我會在幾個小時後嘗試這個 – k102 2011-06-06 14:01:23

+0

太棒了!這工作。我不得不進行兩次更正代碼:'$過程[] = proc_open($命令,$描述符,$管道);'和'0 =>陣列( 「文件」, 「的/ dev /空」, 'R' ),...' – k102 2011-06-07 05:28:02

+0

@ k102噢,是的,對不起。我無法測試它在哪裏。我會在我的答案中解決它。 – zneak 2011-06-07 15:30:33

1

考慮使用microtime()函數。例2這個頁面上是有用的:

http://php.net/manual/en/function.microtime.php 

編輯:這種方法是行不通的,因爲在評論中指出,該過程在後臺lauched。我無法提出更好的方法。

+0

我知道這個功能,但是如何使用它?我的「父」腳本不等待它的孩子,爲了這個目的,他們沒有產生輸出 – k102 2011-06-06 13:54:31

+0

命令在後臺啓動(注意'&'在'$ command'結束),所以這一切將測量是啓動流程花費的時間。 – zneak 2011-06-06 13:56:00

+0

根據對'EXEC()'的手冊頁,通過傳遞適當的參數,你可以得到它,以填補發出的命令的輸出和返回值的變量。對我來說,建議'exec()'必須等到命令完成後才返回,而不是啓動一個進程然後讓它運行。但也許我錯了?或者也許你的「孩子」腳本自己創建過程?我不清楚你的劇本是如何運作的。 – Hammerite 2011-06-06 13:58:52

1

您不能請求在正常操作系統上執行的時間(這是系統調用並由內核處理)。爲此,你需要一個實時操作系統。

但是你可以通過記錄每個實例計算它啓動需要多少時間。比計算該數據集的平均值。

microtime可以給你當前的時間。做到這一點,像這樣:

while(/** list proc */) 
{ 
$starttime = microtime(); 
proc_open(/** some syntax here */); 
$endtime = microtime() - $starttime; 
//store time here 
} 
+0

程序不會並行運行。 – zneak 2011-06-06 13:59:33

+0

第一句話說「我試圖在php中爲我的任務實現某種'多處理'。」不會建議讓所有的連續再次擊敗這個目的? – zneak 2011-06-08 14:45:15

+0

問題是,「我如何計算我的所有scan_part.php需要執行的時間?」 fork的時間只是這個答案的一部分:OP想要知道總執行時間,而不是花費多少時間來產生進程(並且要將控制權交還給腳本)。使用沒有'proc_close'的'proc_open',你仍然沒有達到這個目標。 – zneak 2011-06-09 15:32:23

1

scan_part.php腳本是否輸出調用腳本期望/接受的任何輸入內容?如果沒有,你可以使用/usr/bin/time計算scan_part腳本的運行時間:

exec('/usr/bin/time /usr/bin/php scan_part.php &'); 

返回是這樣的:

0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 4192maxresident)k 
0inputs+0outputs (0major+318minor)pagefaults 0swaps 

,你可以解析的時間。這樣可以讓您獲得執行時間而無需修改scan_parts。另一方面,如果scan_parts通常不會產生輸出,並且您可以/將會修改它,那麼使用幾個microtime(true)調用來包裝scan_parts的內容並輸出差異會更簡單。

$start = microtime(true); 
.... do the core of scan_parts here 
echo microtime(true) - $start; // output the runtime here 
exit(); 

這給你一個單一的時間值返回,節省您的/usr/bin/time東西parseing開銷。

0

您可以使用microtime(),如果您想對整個應用程序進行基準測試,您也可以查看XDebug,它會爲您提供關於應用程序性能的詳細報告。

對於windows Wampserver的最新版本來包裝的XDebug的和webgrind。對於linux來說,安裝也很簡單。

參見:http://code.google.com/p/webgrind/