0

我成功找到(我认为)到下一小时开始之前必须经过多少微秒,但usleep()函数显示警告

微秒数必须大于等于 0

$min = (integer)date('i');
$sec = (integer)date('s');
list($microsec, $tmp) = explode(' ', microtime());
$microsec = (integer)str_replace("0.", "", $microsec);
$min_dif = 59 - $min;
$sec_dif = 59 - $sec;
$microsec_dif = 100000000 - $microsec;
$dif_in_micro = $sec_dif * 100000000 + $min_dif * 6000000000 + 
$microsec_dif;
echo $dif_in_micro;
usleep($dif_in_micro);

非常感谢您的回答,我最终使用了以下内容

$seconds_to_wait = 3540 - (integer)date('i') * 60 + 59 - (integer)date('s');
list($microsec, $tmp) = explode(' ', microtime());
$microsec_to_wait = 1000000 - $microsec * 1000000;
sleep($seconds_to_wait);
usleep($microsec_to_wait);
$now = DateTime::createFromFormat('U.u', microtime(true));
file_put_contents("finish_time.txt", $now->format("m-d-Y H:i:s.u") . PHP_EOL, FILE_APPEND);
4

2 回答 2

0

在您的情况下,您的时基不是微秒,而是 10ns 分辨率。

microtime() 以秒为单位提供带 8 位小数的时间。您正在剥离前导 0。并使用八位小数。您通过写作考虑了这一点$microsec_dif = 1E8 - $microsec;。您将结果发送到 usleep(),而无需补偿 100 倍。这将使您的超时时间达到预期的 100 倍。并且可能会出现整数溢出。

usleep 需要一个整数作为时间。最大值约为 2E9 µs。有了这个限制,您不能等待超过 2000 秒的单个呼叫。

这是我的代码:

$TimeNow=microtime(true);
$SecondsSinceLastFullHour = $TimeNow - 3600*floor($TimeNow/3600);
//echo ("Wait " .   (3600 - SecondsSinceLastFullHour) . " seconds.");
$Sleeptime=(3600.0 - $SecondsSinceLastFullHour); //as float
//Maximum of $Sleeptime is 3600    
//usleep(1e6*$Sleeptime); //worst case 3600E6 won't fit into integer.
//...  but 1800E6 does. So lets split the waiting time in to halfes.
usleep(500000*$Sleeptime);
usleep(500000*$Sleeptime);
于 2019-06-16T12:24:05.950 回答
0

由于您需要比秒更高的精度,所以我认为我们需要同时使用它们。
首先我们等待几秒钟直到我们接近然后我们计算微秒并再次等待。

$Seconds = (microtime(true) - 3600*floor(microtime(true)/3600))-2;
sleep(3600 - $Seconds);
//Code above should wait until xx:59:58
// Now your code should just work fine below here except we shouldn't need minutes

$sec = (integer)date('s');
list($microsec, $tmp) = explode(' ', microtime());
$microsec = (integer)str_replace("0.", "", $microsec);
$sec_dif = 59 - $sec;
$microsec_dif = 100000000 - $microsec;
$dif_in_micro = $sec_dif * 100000000  + $microsec_dif;
echo $dif_in_micro;
usleep($dif_in_micro);
于 2019-06-16T14:40:16.360 回答