算法面試(2)------休眠函數sleep_for和sleep_until

  • 操作系統:ubuntu22.04
  • IDE:Visual Studio Code
  • 編程語言:C++11

算法描述

這兩個函數都定義在 頭文件中,屬于 std::this_thread 命名空間,用于讓當前線程暫停執行一段時間。

函數功能
sleep_for(rel_time)讓當前線程休眠一段相對時間(例如:休眠 100 毫秒)
sleep_until(abs_time)讓當前線程休眠到某個絕對時間點(例如:休眠到 2025年9月15日中午12:00)

函數原型

#include <thread>
#include <chrono>// 1. 休眠一段相對時間
template <class Rep, class Period>
void std::this_thread::sleep_for(const std::chrono::duration<Rep, Period>& rel_time);// 2. 休眠到某個絕對時間點
template <class Clock, class Duration>
void std::this_thread::sleep_until(const std::chrono::time_point<Clock, Duration>& abs_time);

?? 注意:如果傳入負的 rel_time,sleep_for 的行為等同于不休眠(立即返回)。

sleep_for 詳解:休眠一段相對時間

? 語法示例:

using namespace std::chrono;// 休眠 100 毫秒
std::this_thread::sleep_for(100ms);// 或者寫成:
std::this_thread::sleep_for(milliseconds(100));
std::this_thread::sleep_for(seconds(1));        // 休眠 1 秒
std::this_thread::sleep_for(microseconds(500)); // 500 微秒

🧠 工作原理:

  • 當前線程調用 sleep_for 后,會進入阻塞狀態(blocked)。
  • 操作系統將其從 CPU 調度隊列中移除。
  • 經過指定時間后,操作系統將線程重新放入就緒隊列,等待調度執行。
  • 線程恢復執行。

?? 注意事項:

  • 實際休眠時間 ≥ 指定時間
    因為操作系統調度不是實時的,sleep_for 只保證“至少休眠這么長時間”,但可能更長(尤其在系統負載高時)。

  • 精度取決于系統和時鐘
    通常系統時鐘精度為 1~15 毫秒,所以 sleep_for(1us) 可能實際休眠 1ms。

  • 可被中斷嗎?
    在標準 C++ 中,不能被信號或外部事件中斷(不像 POSIX 的 sleep())。一旦調用,必須等到時間結束。

使用場景
場景1:控制循環頻率(如游戲主循環、傳感器采樣)

while (running) 
{read_sensor();process_data();std::this_thread::sleep_for(10ms); // 控制每 10ms 執行一次
}

場景2:重試機制中的退避策略(Retry with Backoff)

for (int i = 0; i < 3; ++i) 
{if (try_connect()) break;std::this_thread::sleep_for(std::chrono::milliseconds(100 * (i + 1))); // 遞增等待
}

sleep_until 詳解:休眠到某個絕對時間點

? 語法示例:

using namespace std::chrono;// 獲取當前時間 + 2 秒
auto now = system_clock::now();
auto two_seconds_later = now + seconds(2);
std::this_thread::sleep_until(two_seconds_later);// 或者指定一個具體時間點(比如明天上午 9:00)
auto tomorrow = system_clock::now() + hours(24);
auto nine_am = std::chrono::time_point_cast<hours>(tomorrow);
nine_am += hours(9); // 假設今天是 0 點,加 9 小時
std::this_thread::sleep_until(nine_am);

🧠 工作原理:

  • sleep_until 接收一個 time_point 類型的時間點。
  • 線程會一直阻塞,直到系統時鐘達到或超過該時間點。
  • 如果當前時間已經晚于或等于目標時間點,則 sleep_until 立即返回,不休眠。

? 使用場景
場景1:定時任務(如每天凌晨執行)

void run_daily_task_at_midnight() 
{while (true) {auto now = system_clock::now();auto tomorrow = system_clock::from_time_t(std::chrono::system_clock::to_time_t(now) + 86400); // 明天 00:00:00auto midnight = std::chrono::time_point_cast<seconds>(tomorrow);std::this_thread::sleep_until(midnight);perform_daily_backup();}
}

場景2:多個線程同步到同一時間點啟動

auto start_time = std::chrono::system_clock::now() + std::chrono::seconds(5);// 所有線程都調用:
std::this_thread::sleep_until(start_time);
// 從而實現“5秒后同時開始”

💡 這比每個線程自己計算 sleep_for(5s) 更精確,避免了啟動延遲累積誤差。

sleep_for vs sleep_until 對比

特性sleep_forsleep_until
時間類型duration(持續時間)time_point(時間點)
語義“我要睡 5 秒”“我要睡到明天 9:00”
是否受系統時間調整影響是(如果系統時間被修改)
適合場景延遲、重試、節流定時任務、時間同步
若目標時間已過休眠指定時間立即返回(不休眠)

?? 注意:sleep_until 使用的是 system_clock,如果用戶手動調整了系統時間,可能導致線程提前喚醒或延遲喚醒。

如果需要更穩定的時鐘,可使用 steady_clock(見下文)。

推薦使用 steady_clock 避免系統時間跳變

雖然 system_clock 是最常用的時鐘,但它受系統時間調整(如 NTP 同步、手動修改)影響。

對于延遲控制類任務,建議使用 steady_clock,它是單調遞增的,不會倒退。
示例:使用 steady_clock 的 sleep_until

auto start = std::chrono::steady_clock::now();
auto deadline = start + std::chrono::milliseconds(100);std::this_thread::sleep_until(deadline); // 推薦用于定時延遲
steady_clock 不受系統時間修改影響,更適合做超時、延遲等操作。

常見誤區與注意事項

? 誤區1:sleep_for(1ms) 一定能精確休眠 1ms

→ 錯!受操作系統調度精度限制,實際可能休眠 1~15ms。
? 誤區2:sleep_until 絕對可靠

→ 如果系統時間被手動調整或 NTP 校正,system_clock 時間點可能跳變,導致提前或延遲喚醒。
? 誤區3:可以在任意線程調用

→ 可以,但注意:主線程調用也會阻塞整個程序。
? 最佳實踐:

延遲控制 → 優先用 sleep_for + steady_clock
定時任務 → 用 sleep_until + system_clock
高精度需求 → 考慮使用平臺特定 API(如 nanosleep on Linux)

完整示例代碼

#include <iostream>
#include <thread>
#include <chrono>int main()
{using namespace std::chrono;std::cout << "Start: " << system_clock::now().time_since_epoch().count() << std::endl;// 1. sleep_for:休眠 2 秒std::cout << "Sleeping for 2s..." << std::endl;std::this_thread::sleep_for(seconds(2));// 2. sleep_until:休眠到 3 秒后auto target = steady_clock::now() + milliseconds(1500);std::cout << "Sleeping until steady time point..." << std::endl;std::this_thread::sleep_until(target);std::cout << "Done!" << std::endl;return 0;
}

總結

函數用途推薦時鐘注意事項
sleep_for(duration)休眠一段相對時間steady_clock保證最小休眠時間
sleep_until(time_point)休眠到某個絕對時間system_clock受系統時間調整影響

? 一句話總結:

用 sleep_for 控制“延遲多久”,
用 sleep_until 控制“什么時候開始”。

它們是多線程中實現節流、重試、定時、同步啟動等行為的基礎工具,理解其差異和適用場景,能讓你寫出更健壯的并發程序。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/96834.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96834.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96834.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

貪心算法應用:5G網絡切片問題詳解

Java中的貪心算法應用&#xff1a;5G網絡切片問題詳解 1. 5G網絡切片問題概述 5G網絡切片是將物理網絡劃分為多個虛擬網絡的技術&#xff0c;每個切片可以滿足不同業務需求&#xff08;如低延遲、高帶寬等&#xff09;。網絡切片資源分配問題可以抽象為一個典型的優化問題&…

Android WorkManager的概念和使用

1. WorkManager基礎與核心概念 1.1 WorkManager概述 WorkManager是Android Jetpack架構組件庫的核心成員&#xff0c;專為管理可靠的后臺任務而設計。它提供了一套統一的API&#xff0c;用于調度需保障執行的延遲型異步任務&#xff08;如數據同步、日志上傳&#xff09;&…

容器使用卷

1.創建一個卷并讓容器掛載該卷1.創建一個卷[roothost1 ~]# docker volume create test-vol test-vol2.列出本地 Docker 主機上的卷[roothost1 ~]# docker volume ls DRIVER VOLUME NAME local test-vol3.查看該卷的詳細信息[roothost1 ~]# docker volume inspect test-v…

高數基礎知識(下)②

文章目錄七、微分方程7.3 高階線性微分方程7.3.1 線性微分方程的解的結構7.3.2 常系數齊次線性微分方程7.3.3 常系數非齊次線性微分方程八、多元函數微分學8.1 偏導數8.2 全微分8.3 基本定理8.4 復合函數微分法8.5 隱函數微分法8.6 多元函數的極值8.6.1 無條件極值8.6.2 條件極…

從0°到180°,STM32玩轉MG996R舵機

1.MG996R舵機的性能參數參數數值產品型號MG995/MG996R產品重量55 g工作扭矩13 kgcm反應速度53-62 R/M使用溫度-30C ~ 55C死區設置4 微秒插頭類型JR、FUTABA 通用轉動角度180&#xff08;左90&#xff0c;右90&#xff09;舵機類型數碼舵機使用電壓3.0 - 7.2 V工作電流100 mA結構…

[frontend]mermaid code2image

hello everyone, welcome to my bolg, here i will introduce something interesting, and if you are interested it, please just let me know. follow me and send me a message are both avaiable. what is mermaid? Mermaid 是一個工具&#xff0c;它能讓你用簡單的文字代…

Jakarta EE 在 IntelliJ IDEA 中開發簡單留言板應用的實驗指導(附完整代碼)

Jakarta EE 在 IntelliJ IDEA 中開發簡單留言板應用的實驗指導(附完整代碼) 摘要:實驗基于Jakarta EE 9+(兼容Tomcat 10+)、Maven作為構建工具,并在IntelliJ IDEA 2023.2(Community版免費)中進行。項目使用Maven Archetype WebApp模板生成基礎結構,然后升級到J…

JavaScript經典面試題一(JavaScript基礎)

目錄 一、JavaScript中的變量提升 1. 機制 2. 示例 3. 注意事項 4. 總結 二、var、let和const的區別。 1. 作用域&#xff08;Scope&#xff09; 2. 變量提升&#xff08;Hoisting&#xff09; 3. 重新賦值和重新聲明 4. 示例 示例1&#xff1a;作用域和塊級行為 示…

數據庫造神計劃第七天---增刪改查(CRUD)(3)

&#x1f525;個人主頁&#xff1a;尋星探路 &#x1f3ac;作者簡介&#xff1a;Java研發方向學習者 &#x1f4d6;個人專欄&#xff1a;《從青銅到王者&#xff0c;就差這講數據結構&#xff01;&#xff01;&#xff01;》、 《JAVA&#xff08;SE&#xff09;----如此簡單&a…

AWS SQS 可觀測性最佳實踐

AWS SQS AWS SQS&#xff08;Amazon Simple Queue Service&#xff09;是一種完全托管的消息隊列服務&#xff0c;用于在分布式系統中解耦和緩沖消息。它支持高可用性、可擴展性和安全性&#xff0c;能夠處理大量消息&#xff0c;確保消息的可靠傳輸和順序性。開發者可以輕松集…

AI推理范式:從CoT到ReAct再到ToT的進化之路

在人工智能領域&#xff0c;如何讓模型像人類一樣進行復雜推理和問題解決&#xff0c;一直是核心挑戰。近年來&#xff0c;思維鏈&#xff08;Chain-of-Thought, CoT&#xff09;、推理與行動&#xff08;ReAct&#xff09; 和 思維樹&#xff08;Tree-of-Thoughts, ToT&#x…

2025時序數據庫選型:深入解析IoTDB從主從架構基因到AI賦能的創新之路

原創經驗總結,拒絕空談,用數據和實戰說話 時序數據時代的"四重考驗" 在智慧工廠、新能源車、金融市場等場景中,每秒百萬級的數據點如潮水般涌來。這些時序數據背后隱藏著四大核心挑戰:極高的寫入并發、強時間關聯性查詢、海量數據生命周期管理,以及亂序與高基…

深入淺出LVS負載均衡群集:原理、分類與NAT模式實戰部署

深入淺出LVS負載均衡群集&#xff1a;原理、分類與NAT模式實戰部署 文章目錄深入淺出LVS負載均衡群集&#xff1a;原理、分類與NAT模式實戰部署一、企業群集&#xff1a;從單臺服務器到分布式架構的必然選擇1. 什么是群集&#xff1f;2. 為什么需要群集&#xff1f;二、企業群集…

Flash Table實測:JAI賦能低代碼開發,重塑企業級應用構建范式

目錄&#x1f50d; 引言1.1 什么是Flash Table1.2 低代碼平臺的進化與FlashTable的革新?FlashTable背景&#xff1a;為什么需要新一代低代碼平臺&#xff1f;2.1 傳統開發的痛點2.2 低代碼平臺的局限2.3 FlashTable的差異化定位&#x1f4bb; FlashTable安裝&#xff1a;Docke…

SonarQube代碼質量管理平臺本地化搭建和使用

SonarQube 是一個開源的代碼質量管理平臺&#xff0c;主要用于持續檢查代碼質量&#xff0c;支持多種編程語言。 本文章記錄了在windows環境中&#xff0c;搭建和使用SonarQube的完整過程。 ①SonarQube平臺搭建 SonarQube最新社區版本下載地址&#xff1a; https://www.son…

基于雙向LSTM深度學習網絡模型的文本序列推薦系統matlab仿真

目錄 1.程序功能描述 2.測試軟件版本以及運行結果展示 3.部分程序 4.算法理論概述 5.完整程序 1.程序功能描述 在信息爆炸的時代&#xff0c;用戶面臨著海量文本信息的篩選難題&#xff0c;文本序列推薦系統應運而生。雙向長短期記憶網絡&#xff08;Bi-directional Long …

Transformer實戰(17)——微調Transformer語言模型進行多標簽文本分類

Transformer實戰(17)——微調Transformer語言模型進行多標簽文本分類 0. 前言 1. 多標簽文本分類 2. 數據加載與處理 3. 模型微調 小結 系列鏈接 0. 前言 與單標簽分類不同,多標簽分類要求模型能夠為同一文本分配多個相關標簽,這在新聞分類、文獻標注、內容推薦等場景中尤…

開源 C++ QT Widget 開發(十六)程序發布

文章的目的為了記錄使用C 進行QT Widget 開發學習的經歷。臨時學習&#xff0c;完成app的開發。開發流程和要點有些記憶模糊&#xff0c;趕緊記錄&#xff0c;防止忘記。 相關鏈接&#xff1a; 開源 C QT Widget 開發&#xff08;一&#xff09;工程文件結構-CSDN博客 開源…

MATLAB2-結構化編程和自定義函數-臺大郭彥甫視頻

目錄 if elseif else switch case otherwise while exercise練習 for 預宣告 練習題 break tips編程的小技巧 functions函數 練習題 函數句柄 if elseif else 如果condition為真&#xff0c;執行語句 if condition1statement1 elseif condition2statement2 elsest…

LVGL移植2048小游戲全攻略

目錄 準備腳手架 修改源碼 對接觸摸 測試編譯 測試運行 這一節將以一個已經編寫好的 lvgl 小游戲 2048 描述如何將已經編寫完成的 lvgl 程序移植到開發板上。 準備腳手架 在這之前&#xff0c;我們先準備基礎的 LVGL 腳手架。可以直接從 lv_g2d_test 里復制過來進行修改…