C++標準庫中時鐘(Clock)
這段內容主要介紹了C++標準庫中**時鐘(Clock)**的概念和分類,以及它們在時間測量中的作用。以下是關鍵信息的解讀:
一、時鐘的核心特性
C++中的時鐘是一個類,提供以下四個基本屬性:
-
當前時間
通過靜態成員函數now()
獲取,返回類型為time_point
。std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
-
時間表示類型
通過time_point
成員類型定義,通常是std::chrono::time_point<Clock, Duration>
。 -
時鐘精度(Tick Period)
表示時鐘的最小時間間隔,使用std::ratio
模板定義。例如:- 每秒25次滴答:
std::ratio<1,25>
(40毫秒) - 每2.5秒一次滴答:
std::ratio<5,2>
(2.5秒)
- 每秒25次滴答:
-
是否為穩定時鐘(Steady Clock)
通過靜態成員is_steady
判斷,若為true
表示時鐘不可調,適用于測量時間間隔。
二、三種標準時鐘
時鐘類型 | 特性 | 典型用途 |
---|---|---|
std::chrono::system_clock | 系統實時時鐘,可調整(如NTP同步)is_steady = false 支持與 time_t 互轉 | 日期時間顯示、文件時間戳 |
std::chrono::steady_clock | 穩定時鐘,不可調整is_steady = true 保證單調遞增 | 超時計算、性能測量 |
std::chrono::high_resolution_clock | 最高精度時鐘(可能是其他時鐘的別名) tick period最小 | 需要高精度的時間測量 |
三、穩定時鐘 vs 系統時鐘
1. 穩定時鐘(Steady Clock)
- 特性:
- 時間單調遞增,不會因系統時間調整而回退。
- 適用于測量相對時間間隔(如超時、耗時統計)。
- 示例:
auto start = std::chrono::steady_clock::now(); // 執行耗時操作 auto end = std::chrono::steady_clock::now(); auto duration = end - start; // 可靠的時間間隔
2. 系統時鐘(System Clock)
- 特性:
- 反映真實世界時間,但可能因調整(如夏令時、NTP同步)而回退。
- 支持與
time_t
互轉,便于格式化輸出。
- 示例:
auto now = std::chrono::system_clock::now(); std::time_t t = std::chrono::system_clock::to_time_t(now); std::cout << "Current time: " << std::ctime(&t); // 轉換為字符串
四、時鐘精度與實際行為
-
理論精度 vs 實際精度
- 時鐘的
period
定義理論最小間隔,但實際精度受硬件限制。 - 例如,
high_resolution_clock
的period
可能為std::ratio<1, 1000000000>
(納秒),但實際可能只能達到微秒級。
- 時鐘的
-
非均勻滴答
- 系統時鐘的
now()
可能返回比之前更早的時間(如時間回撥)。 - 穩定時鐘保證
now()
單調遞增,適合循環超時檢測:auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(10); while (std::chrono::steady_clock::now() < deadline) {// 執行任務,不會因系統時間調整導致超時失效 }
- 系統時鐘的
五、常見應用場景
-
超時控制
// 使用steady_clock計算超時點 auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(500);// 等待操作,檢查是否超時 while (condition_not_met()) {if (std::chrono::steady_clock::now() > timeout) {throw std::runtime_error("Operation timed out");}std::this_thread::sleep_for(std::chrono::milliseconds(10)); }
-
性能測量
auto start = std::chrono::high_resolution_clock::now(); expensive_operation(); auto end = std::chrono::high_resolution_clock::now(); std::cout << "Operation took " << std::chrono::duration<double, std::milli>(end - start).count()<< " ms" << std::endl;
-
時間點轉換
// 系統時鐘轉time_t std::time_t current_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());// 從time_t構造時間點 std::chrono::system_clock::time_point tp = std::chrono::system_clock::from_time_t(current_time);
六、注意事項
-
避免混用時鐘類型
- 不同時鐘的
time_point
不可直接比較,需通過duration_cast
轉換。
- 不同時鐘的
-
時鐘選擇原則
- 需要真實時間(如文件時間戳)→ 使用
system_clock
。 - 需要可靠時間間隔(如超時、耗時統計)→ 使用
steady_clock
。 - 需要最高精度(如科學計算)→ 使用
high_resolution_clock
。
- 需要真實時間(如文件時間戳)→ 使用
-
時鐘實現差異
high_resolution_clock
可能是system_clock
或steady_clock
的別名,具體取決于平臺。
七、總結
C++的時鐘系統通過 system_clock
、steady_clock
和 high_resolution_clock
提供了靈活的時間測量能力:
- 系統時鐘:與現實時間同步,但可能非單調。
- 穩定時鐘:保證時間單調遞增,適合測量時間間隔。
- 高精度時鐘:提供平臺支持的最高精度。
合理選擇時鐘類型是編寫可靠時間敏感代碼的關鍵,特別是在超時控制、性能分析和分布式系統同步等場景中。
這段內容詳細介紹了C++標準庫中std::chrono::duration
的核心概念、用法及應用場景,以下是結構化解讀:
Duration
一、duration
的基本概念
1. 模板定義與參數
std::chrono::duration<Rep, Period>
是表示時間間隔的類模板:
Rep
:表示時間間隔的數值類型(如int
、double
)。Period
:時間單位的比例(如std::ratio<60,1>
表示1分鐘=60秒)。
2. 核心特性
// 示例:定義10分鐘的duration
std::chrono::duration<int, std::ratio<60, 1>> ten_minutes(10);// 等價于預定義類型
std::chrono::minutes ten_minutes(10);
二、預定義時間單位
類型別名 | 對應duration 定義 | 示例 |
---|---|---|
nanoseconds | duration<int64_t, nano> | 10ns |
microseconds | duration<int64_t, micro> | 100us |
milliseconds | duration<int64_t, milli> | 1000ms |
seconds | duration<int64_t> | 10s |
minutes | duration<int64_t, ratio<60>> | 5min |
hours | duration<int64_t, ratio<3600>> | 24h |
特點:
- 自動選擇足夠大的整數類型,支持表示超過500年的時間間隔。
- 支持SI單位前綴(如
atto
、centi
、kilo
等)。
三、C++14時間字面值后綴
1. 整數字面值
using namespace std::chrono_literals;auto one_day = 24h; // hours(24)
auto half_hour = 30min; // minutes(30)
auto max_delay = 500ms; // milliseconds(500)
auto precision = 100ns; // nanoseconds(100)
2. 浮點數支持
auto float_duration = 2.5min; // duration<double, ratio<60>>
auto precise = 0.5ms; // duration<double, milli>
注意:浮點數字面值會使用未指定的浮點類型,若需精確控制類型,需手動構造:
std::chrono::duration<float, std::milli> precise(0.5f); // 顯式指定float類型
四、時間單位轉換
1. 隱式轉換(無精度損失)
std::chrono::hours h(1);
std::chrono::minutes m = h; // 隱式轉換:1h = 60min
2. 顯式轉換(可能截斷)
std::chrono::milliseconds ms(54802);
std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(ms);
// s.count() = 54(54802ms = 54s + 802ms,截斷取整)
3. 四舍五入轉換
std::chrono::milliseconds ms(54802);
std::chrono::seconds s = std::chrono::round<std::chrono::seconds>(ms);
// s.count() = 55(54802ms ≈ 55s)
五、算術操作
1. 基本運算
std::chrono::seconds a(10), b(20), c;c = a + b; // 30s
c = b - a; // 10s
c = a * 2; // 20s
c = b / 2; // 10s
2. 復合運算
std::chrono::minutes m(1);
m += std::chrono::seconds(30); // 1min30s
m -= std::chrono::seconds(60); // 30s
m *= 2; // 1min
3. 比較運算
std::chrono::seconds a(10), b(20);
bool is_less = a < b; // true
bool is_equal = a == b; // false
六、在異步操作中的應用
1. 超時控制
std::future<int> fut = std::async([] { std::this_thread::sleep_for(std::chrono::seconds(1));return 42;
});// 等待35毫秒
if (fut.wait_for(std::chrono::milliseconds(35)) == std::future_status::ready) {std::cout << "Result: " << fut.get() << std::endl;
} else {std::cout << "Timeout!" << std::endl;
}
2. 狀態檢查
std::promise<void> prom;
std::future<void> fut = prom.get_future();// 循環檢查狀態,總超時1秒
auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(1);
while (std::chrono::steady_clock::now() < deadline) {if (fut.wait_for(std::chrono::milliseconds(100)) == std::future_status::ready) {break;}std::cout << "Waiting..." << std::endl;
}
七、關鍵注意事項
-
精度與平臺差異
- 實際時鐘精度可能低于
duration
理論精度(如系統僅支持毫秒級,nanoseconds
會被舍入)。
- 實際時鐘精度可能低于
-
時鐘選擇
- 超時等待使用
steady_clock
(避免系統時鐘調整影響):// 正確:使用steady_clock的duration std::this_thread::sleep_for(std::chrono::seconds(1));
- 超時等待使用
-
類型安全
- 不同
duration
不可直接運算,需轉換:std::chrono::seconds s(1); std::chrono::milliseconds ms = s; // 正確:seconds→milliseconds // std::chrono::minutes m = s; 錯誤:需顯式轉換
- 不同
八、典型應用場景
1. 性能測量
auto start = std::chrono::high_resolution_clock::now();
do_expensive_work();
auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Work took " << duration.count() << " ms" << std::endl;
2. 心跳檢測
auto last_heartbeat = std::chrono::steady_clock::now();while (is_running()) {do_work();if (std::chrono::steady_clock::now() - last_heartbeat > std::chrono::seconds(5)) {send_heartbeat();last_heartbeat = std::chrono::steady_clock::now();}
}
九、總結
std::chrono::duration
通過模板設計提供了類型安全的時間間隔表示,結合預定義類型和字面值后綴,使代碼更簡潔易讀。其核心優勢在于:
- 類型安全:編譯期檢查時間單位,避免邏輯錯誤。
- 精確控制:支持從納秒到小時的任意時間單位。
- 跨平臺兼容:統一時間處理接口,屏蔽底層差異。
在多線程編程中,duration
與 future
、thread
等組件配合,實現精準的超時控制和性能測量,是現代C++并發編程的基礎工具之一。
C++ 時間點(time_point)詳解:從概念到實踐
一、時間點的基本定義與結構
std::chrono::time_point
是 C++ 標準庫中表示時間點的類模板,它就像時間軸上的一個“坐標點”,其核心定義如下:
template <class Clock, class Duration>
class time_point;
- 第一個模板參數(Clock):指定時間點所基于的時鐘類型(如系統時鐘
system_clock
、高分辨率時鐘high_resolution_clock
)。 - 第二個模板參數(Duration):指定時間點的計量單位(如
seconds
、milliseconds
)。
核心概念——紀元(Epoch):
每個時鐘都有一個“紀元”作為時間計算的起點(類似數軸的原點)。例如:
system_clock
的紀元通常是 1970-01-01 00:00:00(Unix 時間戳起點)。high_resolution_clock
的紀元可能是程序啟動的瞬間。
雖然無法直接查詢紀元的具體時間,但可以通過time_since_epoch()
方法獲取時間點距離紀元的時間間隔:
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
std::chrono::seconds since_epoch = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
std::cout << "距離紀元過去了:" << since_epoch.count() << " 秒" << std::endl;
二、時間點的核心操作:加減與計算間隔
-
時間點與時間段的加減
時間點可以通過加減duration
來獲取未來或過去的時間點:// 獲取當前高分辨率時間點 auto now = std::chrono::high_resolution_clock::now(); // 計算 500 納秒后的時間點 auto future = now + std::chrono::nanoseconds(500); // 計算 10 秒前的時間點 auto past = now - std::chrono::seconds(10);
這種操作在設置超時場景中非常實用,例如:
std::future<int> result = std::async(doTask); auto timeout = std::chrono::system_clock::now() + std::chrono::seconds(5); // 5秒后超時 while (result.wait_until(timeout) != std::future_status::ready) {std::cout << "任務未完成,繼續等待..." << std::endl; }
-
時間點之間的差值計算
同一時鐘的兩個時間點相減會得到它們的時間間隔(duration
類型),這是性能分析的常用手段:// 測量函數執行時間 auto start = std::chrono::high_resolution_clock::now();// 執行需要計時的代碼 for (int i = 0; i < 1000000; i++) {// 復雜計算... }auto end = std::chrono::high_resolution_clock::now();// 計算時間差并轉換為秒 auto duration = std::chrono::duration<double, std::chrono::seconds>(end - start); std::cout << "循環執行耗時:" << duration.count() << " 秒" << std::endl;
上述代碼中,
end - start
的結果是duration<long, nano>
(納秒級),通過duration_cast
或直接構造指定單位的duration
可以轉換為秒、毫秒等單位。
三、時鐘類型與時間點的兼容性
C++ 提供了三種主要時鐘類型,它們與時間點的配合需注意:
system_clock
:系統實時時鐘,可通過to_time_t()
和from_time_t()
與日歷時間轉換。steady_clock
:單調時鐘,時間只會遞增(即使系統時間被調整),適合測量時間間隔。high_resolution_clock
:高精度時鐘,通常是steady_clock
的特化版本,適合需要納秒級精度的場景。
重要注意事項:只有基于同一時鐘的時間點才能直接相減,不同時鐘的時間點無法直接比較,因為它們的紀元可能不同。例如:
auto sys_time = std::chrono::system_clock::now();
auto steady_time = std::chrono::steady_clock::now();
// sys_time - steady_time 是未定義行為!
四、實際應用場景
-
任務超時控制
在多線程編程中,等待線程時設置絕對超時時間:std::mutex mtx; std::unique_lock<std::mutex> lock(mtx, std::try_to_lock); if (!lock.owns_lock()) {// 嘗試加鎖失敗,設置 100 毫秒后再次嘗試auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);if (lock.try_lock_until(timeout)) {// 成功獲取鎖} else {// 超時處理} }
-
性能分析與日志記錄
在框架或庫中記錄關鍵流程的耗時:class PerformanceLogger { private:std::chrono::time_point<std::chrono::high_resolution_clock> start_time;public:void start() {start_time = std::chrono::high_resolution_clock::now();}double endAndGetMs() {auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration<double, std::chrono::milliseconds>(end - start_time);return duration.count();} };// 使用示例 PerformanceLogger logger; logger.start(); processBigData(); std::cout << "數據處理耗時:" << logger.endAndGetMs() << " 毫秒" << std::endl;
五、總結:duration 與 time_point 的協作關系
duration
表示“時間段”(如 5 秒、100 毫秒),是相對概念。time_point
表示“時間點”(如 2025-07-02 15:30:00),是絕對概念(基于時鐘紀元)。- 兩者結合使用可以完成從“計算時間間隔”到“設置絕對超時”的各種時間操作,是 C++ 時間處理體系的核心組件。
通過合理運用 time_point
和 duration
,開發者可以在程序中實現精確的時間測量、超時控制和性能分析,這在多線程編程、網絡通信、游戲開發等場景中至關重要。
帶超時機制的條件變量等待
代碼功能概述
這段代碼實現了一個帶超時功能的條件變量等待機制,核心邏輯如下:
- 定義全局變量:條件變量
cv
、狀態標志done
、互斥量m
wait_loop()
函數實現了一個等待循環,最多等待500毫秒- 超時判斷:使用
std::chrono::steady_clock
計算絕對超時時間點 - 循環檢查:當條件變量通知或超時發生時退出循環
#include <condition_variable>
#include <mutex>
#include <chrono>std::condition_variable cv;
bool done;
std::mutex m;bool wait_loop()
{// 計算絕對超時時間點:當前時間 + 500毫秒auto const timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(500);std::unique_lock<std::mutex> lk(m);while (!done) {// 等待條件變量通知或超時if (cv.wait_until(lk, timeout) == std::cv_status::timeout) {break; // 超時則退出循環}}return done; // 返回最終的done狀態
}
wait_until
函數詳解
函數簽名
template <class Rep, class Period, class Clock>
std::cv_status wait_until(std::unique_lock<std::mutex>& lk,const std::chrono::time_point<Clock, std::chrono::duration<Rep, Period>>& timeout_time
);
參數解析
-
lk
:- 類型:
std::unique_lock<std::mutex>&
- 作用:必須持有互斥量
m
的鎖,等待期間會釋放鎖,喚醒后重新獲取。
- 類型:
-
timeout_time
:- 類型:
std::chrono::time_point<Clock, Duration>
- 作用:絕對超時時間點,使用
std::chrono
的時間點類型表示。 - 示例:
std::chrono::steady_clock::now() + std::chrono::milliseconds(500)
- 類型:
返回值機制
wait_until
返回std::cv_status
枚舉值,可能為:
-
std::cv_status::timeout
:- 條件:等待直到超時時間點仍未收到通知。
- 處理:代碼中通過
break
退出循環。
-
std::cv_status::no_timeout
:- 條件:在超時前收到條件變量通知。
- 處理:繼續循環檢查
done
條件(可能因虛假喚醒導致)。
執行流程分析
-
超時時間計算:
使用std::chrono::steady_clock
獲取當前時間,加上500毫秒得到絕對超時時間點timeout
。 -
等待過程:
wait_until
釋放lk
的鎖,將線程置于等待狀態。- 當以下情況發生時,線程被喚醒并重新獲取鎖:
- 其他線程調用
cv.notify_one()
或cv.notify_all()
- 系統時間到達
timeout
時間點(超時)
- 其他線程調用
-
條件檢查:
- 喚醒后檢查返回值:
- 若超時(
timeout
),break退出循環 - 若非超時(
no_timeout
),繼續檢查done
條件(處理虛假喚醒)
- 若超時(
- 喚醒后檢查返回值:
-
結果返回:
無論是否超時,最終返回done
的當前狀態。
關鍵技術點
1. 絕對時間 vs 相對時間
- 絕對時間:
wait_until
使用絕對時間點(如2025-07-02 15:30:00.500
),適合精確控制超時截止時間。 - 相對時間:
wait_for
使用時間段(如500ms
),適合設置相對等待時長。
2. 虛假喚醒處理
- 雖然代碼中使用
while (!done)
循環,但超時后直接break,可能存在隱患:
更安全的做法是超時后仍檢查// 改進版:超時后繼續檢查條件 while (!done) {if (cv.wait_until(lk, timeout) == std::cv_status::timeout) {break;} }
done
狀態,避免因虛假喚醒導致提前退出。
3. 時鐘選擇
- 使用
std::chrono::steady_clock
:
確保時間單調遞增,避免系統時鐘調整(如NTP同步)導致的超時不準確。
典型應用場景
-
網絡請求超時:
bool receive_data(timeout_ms) {bool data_ready = false;{std::unique_lock lk(mutex);auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);while (!data_ready) {if (cv.wait_until(lk, timeout) == std::cv_status::timeout) {break;}}}return data_ready; }
-
任務調度超時:
bool wait_for_task_completion(int task_id, int timeout_seconds) {auto timeout = std::chrono::steady_clock::now() + std::chrono::seconds(timeout_seconds);std::unique_lock lk(mutex);while (tasks[task_id].status != completed) {if (cv.wait_until(lk, timeout) == std::cv_status::timeout) {return false; // 任務超時}}return true; }
總結
wait_until
函數通過絕對時間點實現精確超時控制,是條件變量在超時場景下的核心接口。其工作流程可概括為:
- 計算絕對超時時間點
- 釋放鎖并等待通知/超時
- 喚醒后重新獲取鎖并返回狀態
- 結合循環處理虛假喚醒和超時邏輯
合理使用wait_until
能有效避免線程無限阻塞,是多線程編程中超時控制的關鍵機制。
帶超時機制的條件變量等待示例:生產者-消費者模型
下面是一個使用條件變量超時機制的完整示例,實現了帶超時的生產者-消費者模式。這個示例中,消費者線程會等待生產者提供數據,但設置了超時時間,避免無限阻塞。
#include<iostream>
#include<mutex>
#include<thread>
#include<chrono>
#include<condition_variable>
#include<queue>//the shared resource
bool done = false;
std::mutex mtx;
std::condition_variable cv;
std::queue<int> data_queue;//producer thread function
void producer()
{for (int i = 0; i < 5; i++){std::string data = "Data "+ std::to_string(i);{std::lock_guard<std::mutex> lock(mtx);data_queue.push(i);std::cout << "Produced: " << data << std::endl;}cv.notify_one(); // Notify the consumer that data is availablestd::this_thread::sleep_for(std::chrono::milliseconds(300)); // Simulate work}// Signal that production is done{std::lock_guard<std::mutex> lock(mtx);done = true;}cv.notify_one(); // Notify the consumer that no more data is available
}//consumer thread function
void consumer(int id)
{while (true){std::unique_lock<std::mutex> lock(mtx);//calculate the timeout point : the current time plus 1 secondauto timeout_point = std::chrono::steady_clock::now() + std::chrono::seconds(1);// Wait for data or timeout, use the loop to handle spurious wake-upswhile (data_queue.empty() && !done){if (cv.wait_until(lock, timeout_point) == std::cv_status::timeout){std::cout << "Consumer " << id << " timed out waiting for data." << std::endl;break;//timeout, exit the loop}}// Check if we have been signaled to done or if the queue is empty//when the production has not finished yet, continue to wait for dataif (!done && data_queue.empty()){continue;}//If we have been signaled to done and the queue is empty, exit the loopif (done && data_queue.empty()){std::cout<<" All data consumed by consumer "<<id<<std::endl;break;}// Consume dataint data = data_queue.front();data_queue.pop();std::string data_str = "Data "+std::to_string(data);std::cout << "Consumed by consumer " << id << ": " << data_str << std::endl;// Simulate processing timestd::this_thread::sleep_for(std::chrono::milliseconds(500));}
}int main()
{// Create and start the producer threadstd::thread prod_thread(producer);// Create and start the consumer threadsstd::thread cons_thread1(consumer, 1);std::thread cons_thread2(consumer, 2);// Wait for the threads to finishprod_thread.join();cons_thread1.join();cons_thread2.join();return 0;
}
代碼解析:超時機制的關鍵部分
1. 超時時間計算
auto timeout = std::chrono::steady_clock::now() + std::chrono::seconds(1);
- 使用
steady_clock
確保時間單調遞增,避免系統時鐘調整導致的超時不準確 - 設置1秒的超時時間,可根據需求調整
2. 帶超時的條件變量等待
while (data_queue.empty() && !stop) {if (cv.wait_until(lock, timeout) == std::cv_status::timeout) {std::cout << "Consumer " << id << ": Timeout, no data received" << std::endl;break;}
}
- 使用
wait_until
等待條件變量通知或超時 - 返回
cv_status::timeout
表示等待超時 - 外層循環處理虛假喚醒(即使收到通知,也需重新檢查條件)
3. 超時后的邏輯處理
if (data_queue.empty() && !stop) {continue; // 超時但未停止,繼續下一次循環
}if (stop && data_queue.empty()) {break; // 所有數據處理完畢,退出線程
}
- 超時但未停止時,繼續嘗試獲取數據
- 當生產結束且隊列為空時,消費者線程退出
執行流程說明
-
生產者線程:
- 依次生產5個數據項,每次生產后通知消費者
- 生產完成后標記
stop
為true并通知所有消費者
-
消費者線程:
- 每次等待數據時設置1秒超時
- 收到數據后處理,若超時則輸出提示并繼續嘗試
- 當
stop
為true且隊列為空時,退出線程
-
超時場景:
- 當生產者生產速度較慢時,消費者會多次超時
- 最終生產者完成生產后,消費者處理完剩余數據并退出
常見應用場景
-
網絡通信:
bool receive_data(int socket, std::vector<char>& buffer, int timeout_ms) {// 設置超時時間auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);std::unique_lock<std::mutex> lock(mutex);while (buffer.empty()) {if (cv.wait_until(lock, timeout) == std::cv_status::timeout) {return false; // 接收超時}}// 處理接收到的數據return true; }
-
任務調度系統:
bool wait_for_task(int task_id, int timeout_seconds) {auto timeout = std::chrono::steady_clock::now() + std::chrono::seconds(timeout_seconds);std::unique_lock<std::mutex> lock(mutex);while (tasks[task_id].status == TaskStatus::PENDING) {if (cv.wait_until(lock, timeout) == std::cv_status::timeout) {return false; // 任務執行超時}}return tasks[task_id].status == TaskStatus::COMPLETED; }
關鍵注意事項
-
虛假喚醒處理:
- 始終使用循環檢查條件,而非單次
if
判斷 - 即使收到通知,也可能因虛假喚醒導致條件未滿足
- 始終使用循環檢查條件,而非單次
-
時鐘選擇:
- 優先使用
steady_clock
進行超時計算 system_clock
可能因時間調整導致超時不準確
- 優先使用
-
超時后的資源處理:
- 超時后應處理未完成的操作
- 避免因超時導致資源泄漏或邏輯錯誤
通過這個示例,可以掌握帶超時機制的條件變量使用方法,這在需要避免線程無限阻塞的多線程應用中非常重要。