簡介
`Timer` 毫秒精度的定時器,底層基于 `epoll_wait` 和 `setitimer` 實現(xiàn),數(shù)據(jù)結(jié)構(gòu)使用`最小堆`,可支持添加大量定時器,使用最小堆數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的定時器,類似 JavaScript 的 `setInterval`,`Swoole` 定時器的添加和刪除,全部為內(nèi)存操作,因此性能是非常高的。
Swoole 中的 `Timer` 與 `PHP` 本身的 `pcntl_alarm` 是不同的。`pcntl_alarm` 是基于 `時鐘信號 + tick` 函數(shù)實現(xiàn),一個是最大僅支持到秒,另一個是不支持同時設(shè)定多個定時器程序,性能相對來說會比較差。
間隔時鐘定時器
我們可以通過 `Timer::tick` 來實現(xiàn)間隔時鐘定時器,定時器會持續(xù)觸發(fā),每隔指定時間自動觸發(fā)執(zhí)行回調(diào)函數(shù), 直到調(diào)用 `Timer::clear` 來清除指定的定時器。
$i = 0;
Swoole\Timer::tick(1000, function($id) use ($i) {
global $i;
echo "tick id:$id i:$i \n";
$i++;
});
- 每隔1秒時間觸發(fā)一次回調(diào)函數(shù), 回調(diào)函數(shù)會自動打印一行信息到控制臺。
一次性定時器
需要執(zhí)行一次定時器的時候可以使用 `Timer::after` , 此函數(shù)是一個一次性定時器,與間隔時鐘定時器不同,執(zhí)行完成后就會銷毀,需要注意的是 `Timer::after` 是非阻塞的。
Swoole\Timer::after(2000, function () {
echo "執(zhí)行一次的after\n";
});
- 2秒后執(zhí)行回調(diào)函數(shù),執(zhí)行完成后自動退出。
清除定時器
? `Timer::after` 執(zhí)行完成后會自動退出,不需要清除,而 `Timer::tick` 沒有清除定時器操作,會一直執(zhí)行,直到程序退出。 當(dāng)不需要定時器的時候,我們可以使用 `Timer::clear` 來達到停止定時器的目的,將對應(yīng)定時器 `id` 傳入該方法即可。
? 注意,`Timer::clear` 不能用于清除其他進程的定時器,只作用于當(dāng)前進程。
$i = 0;
Swoole\Timer::tick(1000, function ($id) use ($i) {
global $i;
echo "tick id:$id i:$i \n";
$i++;
if ($i > 10) {
Swoole\Timer::clear($id);
}
});
- 每隔1秒執(zhí)行一次回調(diào)函數(shù),當(dāng) `$i` 自增到10時,關(guān)閉定時器,此時程序會自動退出。
清除所有定時器
? `Timer::clearAll` 用來清除同一進程空間中的計時器?;旧吓c `Timer::clear` 相同,但 `Timer::clearAll` 可以一次性清除所有活動的計時器。
Swoole\Timer::tick(2000, function () {
echo "tick \n";
});
$str = "Swoole";
Swoole\Timer::after(1000, function() use ($str) {
echo "Hello, $str\n";
});
Swoole\Timer::clearAll();
結(jié)尾
? 定時器功能可以很方便的實現(xiàn)定時任務(wù),例如 `CRMEB Pro系統(tǒng)` 中的自動取消訂單、自動確認收貨、自動商品上下架、自動到期租戶等操作就是基于 `Timer::tick` 來實現(xiàn)的。
? [CRMEB Pro系統(tǒng)](https://crmeb.com/web/index/pro) 以卓越的系統(tǒng)性能,個性的后臺操作,豐富的營銷功能,精細化的用戶運營,裂變式分銷,個性化傳播,解決電商引流、推廣難題,幫助企業(yè)打造生態(tài)級B2C盈利模式商城。