我有用PHP实现的伪crone调度程序。项目的核心是一个简单的while循环:
while((time()-$start)<$time_limit) {
//Perform jobs
...
//Sleep a second
sleep(1)
}
现在很明显,如果作业部分花费了大量的时间,比如0.5秒,那么很快就可以跳过一秒钟。在这里,我假设它总是不到一秒钟。
只为你想象:
Timeline:
+0 0
+0.4 0.4 - execution
+1 1.4 - sleep
+0.3 1.7 - execution
+1 2.7 - sleep
+0.6 3.3 - execution
所以,我决定制作一个更智能的睡眠算法。我的想法是花费当前的微秒时间,并寻求我需要多少微秒才能睡到下一秒:
/*Sleep exactly to the next whole second*/
//Get current microtime as xxxxx.yyyyy (so the whole part is seconds)
$utime = microtime(true);
//Get the next whole second by rounding this up
$utime_next = ceil($utime);
//Find some 0.xxx of time that makes the difference
//this+exec time of the scripts in this iteration should be 1
$diff = $utime_next-$utime;
//Sleep for that ammount of usecs
usleep($diff*1000000);
//Log for debug
$this->log("Slept for $diff seconds.");
现在结果似乎非常令人不安。在过去,日志丢失了几秒钟:
[2.3.2014 2:13:08 ] - &gt;信息:&gt;&gt;包括'script.php';
[2.3.2014 2:13:10 ] - &gt;信息:&gt;&gt;包括'script.php';
[2.3.2014 2:13:11] - &gt;信息:&gt;&gt;包括'script.php';
使用usleep的新版本似乎忽略了数学,这更糟糕:
[2.3.2014 2:44: 54 ] - &gt;信息:睡觉 0.67506289482117 秒 [2.3.2014 2:44: 54 ] - &gt;信息:&gt;&gt;包括'script.php';
[2.3.2014 2:44: 54 ] - &gt;信息:睡觉 0.67906403541565 秒 [2.3.2014 2:44: 54 ] - &gt;信息:&gt;&gt;包括'script.php';
那到底是什么?我的计算器确认睡眠时间是0.67506289482117+0.67906403541565 = 1.35412693023682
。我正在使用date
在日志中生成日期。
注意:这是一个有趣的项目。无需解释为什么这是一个坏主意。