當前位置: 首頁> 最新文章列表> 如何結合gettimeofday 和sleep 函數來精確控制任務執行時間?

如何結合gettimeofday 和sleep 函數來精確控制任務執行時間?

gitbox 2025-06-27

一、了解gettimeofdaysleep

  1. 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的返回值是當前時間,單位為秒和微秒,可以用於精確計算任務的執行時間。

  2. 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函數,它允許我們傳遞微秒級別的時間。


二、如何結合gettimeofdaysleep精確控制執行時間

假設你需要在程序中精確控制任務的執行時間,比如任務執行需要在固定的時間間隔內循環進行,但又不希望任務執行時間過長或者過短。我們可以使用gettimeofday獲取當前時間,並結合sleep函數來調整每次執行的間隔。

  1. 獲取當前時間

    我們首先調用gettimeofday來獲取當前的系統時間。這樣可以得知任務開始執行的時間點。

  2. 計算目標時間

    假設我們需要任務每隔100 毫秒執行一次。可以在獲取到開始時間後,計算出下一次任務執行的目標時間。目標時間等於當前時間加上任務執行間隔。

  3. 等待直到目標時間到達

    計算出目標時間後,我們可以通過計算當前時間與目標時間的差值,並使用sleep或者usleep進行精確的等待。這樣可以避免任務的執行時間過長或過短。

  4. 控制任務的精度

    如果希望更加精確控制任務的執行時間,可以在任務執行完畢後再檢查當前時間,確保任務的間隔符合要求。

下面是一個使用gettimeofdaysleep來控制任務執行時間的示例代碼:

 <span><span><span class="hljs-meta">&lt;?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> &gt; </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">?&gt;</span></span><span>
</span></span>

在這個例子中,任務每100 毫秒執行一次。通過gettimeofday函數獲取當前時間,併計算出目標時間,再用usleep函數進行精準的等待。這樣就能實現任務的精確控制,避免由於系統調度或其他因素引起的時間偏差。