2011-06-06 85 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/