gettimeofday 是一个 C 语言标准库函数,通常用于获取当前的系统时间,精度可以达到微秒级。它的声明如下:
<span><span><span class="hljs-type">int</span></span><span> </span><span><span class="hljs-title function_">gettimeofday</span></span><span><span class="hljs-params">(<span class="hljs-keyword">struct</span></span></span><span> timeval *tv, </span><span><span class="hljs-keyword">struct</span></span><span> timezone *tz);
</span></span>
tv 是一个 timeval 结构体,包含了秒数和微秒数;
tz 是时区信息,通常我们可以传递 NULL,因为时区信息不在我们的关注范围内。
gettimeofday 的返回值是当前时间,单位为秒和微秒,可以用于精确计算任务的执行时间。
sleep 函数
sleep 函数用于暂停程序的执行,它的单位是秒,通常用于控制代码的等待时间。它的声明如下:
<span><span><span class="hljs-type">unsigned</span></span><span> </span><span><span class="hljs-type">int</span></span><span> </span><span><span class="hljs-title function_">sleep</span></span><span><span class="hljs-params">(<span class="hljs-type">unsigned</span></span></span><span> </span><span><span class="hljs-type">int</span></span><span> seconds);
</span></span>
但 sleep 函数只能精确到秒级,如果需要更高精度的时间控制,我们可以使用 usleep 函数,它允许我们传递微秒级别的时间。
假设你需要在程序中精确控制任务的执行时间,比如任务执行需要在固定的时间间隔内循环进行,但又不希望任务执行时间过长或者过短。我们可以使用 gettimeofday 获取当前时间,并结合 sleep 函数来调整每次执行的间隔。
获取当前时间
我们首先调用 gettimeofday 来获取当前的系统时间。这样可以得知任务开始执行的时间点。
计算目标时间
假设我们需要任务每隔 100 毫秒执行一次。可以在获取到开始时间后,计算出下一次任务执行的目标时间。目标时间等于当前时间加上任务执行间隔。
等待直到目标时间到达
计算出目标时间后,我们可以通过计算当前时间与目标时间的差值,并使用 sleep 或者 usleep 进行精确的等待。这样可以避免任务的执行时间过长或过短。
控制任务的精度
如果希望更加精确控制任务的执行时间,可以在任务执行完毕后再检查当前时间,确保任务的间隔符合要求。
下面是一个使用 gettimeofday 和 sleep 来控制任务执行时间的示例代码:
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 设置每次任务执行的间隔时间(单位:秒和微秒)</span></span><span>
</span><span><span class="hljs-variable">$interval_sec</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>; </span><span><span class="hljs-comment">// 秒</span></span><span>
</span><span><span class="hljs-variable">$interval_usec</span></span><span> = </span><span><span class="hljs-number">100000</span></span><span>; </span><span><span class="hljs-comment">// 微秒,100毫秒</span></span><span>
</span><span><span class="hljs-comment">// 获取当前时间</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">getCurrentTime</span></span><span>(</span><span><span class="hljs-params"></span></span><span>) {
</span><span><span class="hljs-variable">$time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">gettimeofday</span></span><span>();
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$time</span></span><span>[</span><span><span class="hljs-string">'sec'</span></span><span>] * </span><span><span class="hljs-number">1000000</span></span><span> + </span><span><span class="hljs-variable">$time</span></span><span>[</span><span><span class="hljs-string">'usec'</span></span><span>]; </span><span><span class="hljs-comment">// 返回当前时间的微秒数</span></span><span>
}
</span><span><span class="hljs-comment">// 计算任务执行的目标时间</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">getTargetTime</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-variable">$interval_sec</span></span></span><span>, </span><span><span class="hljs-variable">$interval_usec</span></span><span>) {
</span><span><span class="hljs-variable">$current_time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">getCurrentTime</span></span><span>();
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$current_time</span></span><span> + </span><span><span class="hljs-variable">$interval_sec</span></span><span> * </span><span><span class="hljs-number">1000000</span></span><span> + </span><span><span class="hljs-variable">$interval_usec</span></span><span>;
}
</span><span><span class="hljs-comment">// 模拟一个定时任务</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">performTask</span></span><span>(</span><span><span class="hljs-params"></span></span><span>) {
</span><span><span class="hljs-comment">// 模拟任务执行(例如:处理数据、请求API等)</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Task performed at: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">date</span></span><span>(</span><span><span class="hljs-string">"Y-m-d H:i:s"</span></span><span>) . </span><span><span class="hljs-string">"\n"</span></span><span>;
}
</span><span><span class="hljs-comment">// 主程序</span></span><span>
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-literal">true</span></span><span>) {
</span><span><span class="hljs-comment">// 获取当前时间</span></span><span>
</span><span><span class="hljs-variable">$current_time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">getCurrentTime</span></span><span>();
</span><span><span class="hljs-comment">// 计算目标时间</span></span><span>
</span><span><span class="hljs-variable">$target_time</span></span><span> = </span><span><span class="hljs-title function_ invoke__">getTargetTime</span></span><span>(</span><span><span class="hljs-variable">$interval_sec</span></span><span>, </span><span><span class="hljs-variable">$interval_usec</span></span><span>);
</span><span><span class="hljs-comment">// 执行任务</span></span><span>
</span><span><span class="hljs-title function_ invoke__">performTask</span></span><span>();
</span><span><span class="hljs-comment">// 计算等待时间</span></span><span>
</span><span><span class="hljs-variable">$sleep_time</span></span><span> = </span><span><span class="hljs-variable">$target_time</span></span><span> - </span><span><span class="hljs-title function_ invoke__">getCurrentTime</span></span><span>();
</span><span><span class="hljs-comment">// 如果任务执行时间较短,可以通过 usleep 来精确等待</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$sleep_time</span></span><span> > </span><span><span class="hljs-number">0</span></span><span>) {
</span><span><span class="hljs-title function_ invoke__">usleep</span></span><span>(</span><span><span class="hljs-variable">$sleep_time</span></span><span>); </span><span><span class="hljs-comment">// 等待直到目标时间到达</span></span><span>
}
}
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>
在这个例子中,任务每 100 毫秒执行一次。通过 gettimeofday 函数获取当前时间,并计算出目标时间,再用 usleep 函数进行精准的等待。这样就能实现任务的精确控制,避免由于系统调度或其他因素引起的时间偏差。