C++異步編程里避免超時機制

C++標準庫中時鐘(Clock)

這段內容主要介紹了C++標準庫中**時鐘(Clock)**的概念和分類,以及它們在時間測量中的作用。以下是關鍵信息的解讀:

一、時鐘的核心特性

C++中的時鐘是一個類,提供以下四個基本屬性:

  1. 當前時間
    通過靜態成員函數 now() 獲取,返回類型為 time_point

    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
    
  2. 時間表示類型
    通過 time_point 成員類型定義,通常是 std::chrono::time_point<Clock, Duration>

  3. 時鐘精度(Tick Period)
    表示時鐘的最小時間間隔,使用 std::ratio 模板定義。例如:

    • 每秒25次滴答:std::ratio<1,25>(40毫秒)
    • 每2.5秒一次滴答:std::ratio<5,2>(2.5秒)
  4. 是否為穩定時鐘(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);  // 轉換為字符串
    

四、時鐘精度與實際行為

  1. 理論精度 vs 實際精度

    • 時鐘的 period 定義理論最小間隔,但實際精度受硬件限制。
    • 例如,high_resolution_clockperiod 可能為 std::ratio<1, 1000000000>(納秒),但實際可能只能達到微秒級。
  2. 非均勻滴答

    • 系統時鐘的 now() 可能返回比之前更早的時間(如時間回撥)。
    • 穩定時鐘保證 now() 單調遞增,適合循環超時檢測:
      auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(10);
      while (std::chrono::steady_clock::now() < deadline) {// 執行任務,不會因系統時間調整導致超時失效
      }
      

五、常見應用場景

  1. 超時控制

    // 使用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));
    }
    
  2. 性能測量

    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;
    
  3. 時間點轉換

    // 系統時鐘轉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);
    

六、注意事項

  1. 避免混用時鐘類型

    • 不同時鐘的 time_point 不可直接比較,需通過 duration_cast 轉換。
  2. 時鐘選擇原則

    • 需要真實時間(如文件時間戳)→ 使用 system_clock
    • 需要可靠時間間隔(如超時、耗時統計)→ 使用 steady_clock
    • 需要最高精度(如科學計算)→ 使用 high_resolution_clock
  3. 時鐘實現差異

    • high_resolution_clock 可能是 system_clocksteady_clock 的別名,具體取決于平臺。

七、總結

C++的時鐘系統通過 system_clocksteady_clockhigh_resolution_clock 提供了靈活的時間測量能力:

  • 系統時鐘:與現實時間同步,但可能非單調。
  • 穩定時鐘:保證時間單調遞增,適合測量時間間隔。
  • 高精度時鐘:提供平臺支持的最高精度。

合理選擇時鐘類型是編寫可靠時間敏感代碼的關鍵,特別是在超時控制、性能分析和分布式系統同步等場景中。

這段內容詳細介紹了C++標準庫中std::chrono::duration的核心概念、用法及應用場景,以下是結構化解讀:

Duration

一、duration的基本概念

1. 模板定義與參數

std::chrono::duration<Rep, Period> 是表示時間間隔的類模板:

  • Rep:表示時間間隔的數值類型(如intdouble)。
  • 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定義示例
nanosecondsduration<int64_t, nano>10ns
microsecondsduration<int64_t, micro>100us
millisecondsduration<int64_t, milli>1000ms
secondsduration<int64_t>10s
minutesduration<int64_t, ratio<60>>5min
hoursduration<int64_t, ratio<3600>>24h

特點

  • 自動選擇足夠大的整數類型,支持表示超過500年的時間間隔。
  • 支持SI單位前綴(如attocentikilo等)。

三、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;
}

七、關鍵注意事項

  1. 精度與平臺差異

    • 實際時鐘精度可能低于duration理論精度(如系統僅支持毫秒級,nanoseconds會被舍入)。
  2. 時鐘選擇

    • 超時等待使用steady_clock(避免系統時鐘調整影響):
      // 正確:使用steady_clock的duration
      std::this_thread::sleep_for(std::chrono::seconds(1));
      
  3. 類型安全

    • 不同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 通過模板設計提供了類型安全的時間間隔表示,結合預定義類型和字面值后綴,使代碼更簡潔易讀。其核心優勢在于:

  1. 類型安全:編譯期檢查時間單位,避免邏輯錯誤。
  2. 精確控制:支持從納秒到小時的任意時間單位。
  3. 跨平臺兼容:統一時間處理接口,屏蔽底層差異。

在多線程編程中,durationfuturethread 等組件配合,實現精準的超時控制和性能測量,是現代C++并發編程的基礎工具之一。

C++ 時間點(time_point)詳解:從概念到實踐

一、時間點的基本定義與結構

std::chrono::time_point 是 C++ 標準庫中表示時間點的類模板,它就像時間軸上的一個“坐標點”,其核心定義如下:

template <class Clock, class Duration>
class time_point;
  • 第一個模板參數(Clock):指定時間點所基于的時鐘類型(如系統時鐘 system_clock、高分辨率時鐘 high_resolution_clock)。
  • 第二個模板參數(Duration):指定時間點的計量單位(如 secondsmilliseconds)。

核心概念——紀元(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;
二、時間點的核心操作:加減與計算間隔
  1. 時間點與時間段的加減
    時間點可以通過加減 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;
    }
    
  2. 時間點之間的差值計算
    同一時鐘的兩個時間點相減會得到它們的時間間隔(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++ 提供了三種主要時鐘類型,它們與時間點的配合需注意:

  1. system_clock:系統實時時鐘,可通過 to_time_t()from_time_t() 與日歷時間轉換。
  2. steady_clock:單調時鐘,時間只會遞增(即使系統時間被調整),適合測量時間間隔。
  3. 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 是未定義行為!
四、實際應用場景
  1. 任務超時控制
    在多線程編程中,等待線程時設置絕對超時時間:

    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 {// 超時處理}
    }
    
  2. 性能分析與日志記錄
    在框架或庫中記錄關鍵流程的耗時:

    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_pointduration,開發者可以在程序中實現精確的時間測量、超時控制和性能分析,這在多線程編程、網絡通信、游戲開發等場景中至關重要。

帶超時機制的條件變量等待

代碼功能概述

這段代碼實現了一個帶超時功能的條件變量等待機制,核心邏輯如下:

  • 定義全局變量:條件變量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
);
參數解析
  1. lk

    • 類型:std::unique_lock<std::mutex>&
    • 作用:必須持有互斥量m的鎖,等待期間會釋放鎖,喚醒后重新獲取。
  2. timeout_time

    • 類型:std::chrono::time_point<Clock, Duration>
    • 作用:絕對超時時間點,使用std::chrono的時間點類型表示。
    • 示例:std::chrono::steady_clock::now() + std::chrono::milliseconds(500)
返回值機制

wait_until返回std::cv_status枚舉值,可能為:

  1. std::cv_status::timeout

    • 條件:等待直到超時時間點仍未收到通知。
    • 處理:代碼中通過break退出循環。
  2. std::cv_status::no_timeout

    • 條件:在超時前收到條件變量通知。
    • 處理:繼續循環檢查done條件(可能因虛假喚醒導致)。

執行流程分析

  1. 超時時間計算
    使用std::chrono::steady_clock獲取當前時間,加上500毫秒得到絕對超時時間點timeout

  2. 等待過程

    • wait_until釋放lk的鎖,將線程置于等待狀態。
    • 當以下情況發生時,線程被喚醒并重新獲取鎖:
      • 其他線程調用cv.notify_one()cv.notify_all()
      • 系統時間到達timeout時間點(超時)
  3. 條件檢查

    • 喚醒后檢查返回值:
      • 若超時(timeout),break退出循環
      • 若非超時(no_timeout),繼續檢查done條件(處理虛假喚醒)
  4. 結果返回
    無論是否超時,最終返回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同步)導致的超時不準確。

典型應用場景

  1. 網絡請求超時

    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;
    }
    
  2. 任務調度超時

    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函數通過絕對時間點實現精確超時控制,是條件變量在超時場景下的核心接口。其工作流程可概括為:

  1. 計算絕對超時時間點
  2. 釋放鎖并等待通知/超時
  3. 喚醒后重新獲取鎖并返回狀態
  4. 結合循環處理虛假喚醒和超時邏輯

合理使用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; // 所有數據處理完畢,退出線程
}
  • 超時但未停止時,繼續嘗試獲取數據
  • 當生產結束且隊列為空時,消費者線程退出

執行流程說明

  1. 生產者線程

    • 依次生產5個數據項,每次生產后通知消費者
    • 生產完成后標記stop為true并通知所有消費者
  2. 消費者線程

    • 每次等待數據時設置1秒超時
    • 收到數據后處理,若超時則輸出提示并繼續嘗試
    • stop為true且隊列為空時,退出線程
  3. 超時場景

    • 當生產者生產速度較慢時,消費者會多次超時
    • 最終生產者完成生產后,消費者處理完剩余數據并退出

常見應用場景

  1. 網絡通信

    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;
    }
    
  2. 任務調度系統

    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;
    }
    

關鍵注意事項

  1. 虛假喚醒處理

    • 始終使用循環檢查條件,而非單次if判斷
    • 即使收到通知,也可能因虛假喚醒導致條件未滿足
  2. 時鐘選擇

    • 優先使用steady_clock進行超時計算
    • system_clock可能因時間調整導致超時不準確
  3. 超時后的資源處理

    • 超時后應處理未完成的操作
    • 避免因超時導致資源泄漏或邏輯錯誤

通過這個示例,可以掌握帶超時機制的條件變量使用方法,這在需要避免線程無限阻塞的多線程應用中非常重要。

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

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

相關文章

npm install安裝不成功(node:32388)怎么解決?

如果在執行 npm install 時出現問題&#xff0c;尤其是 node:32388 相關的錯誤&#xff0c;這通常意味著某些依賴或配置出了問題。這里有一些常見的解決方法&#xff0c;你可以嘗試&#xff1a; 1. 清除 npm 緩存 有時候&#xff0c;npm 緩存問題會導致安裝失敗。你可以清除 …

Ubuntu-18.04-bionic 的apt的/etc/apt/sources.list 更換國內鏡像軟件源 筆記250702

Ubuntu-18.04-bionic 的apt的/etc/apt/sources.list更換國內鏡像軟件源 筆記250702 為 Ubuntu 18.04 LTS&#xff08;代號 Bionic Beaver&#xff09;更換 /etc/apt/sources.list 為國內鏡像源 備份/etc/apt/sources.list文件 sudo cp -a /etc/apt/sources.list /etc/apt/sou…

【運維系列】【ubuntu22.04】安裝GitLab

一.下載安裝文件 rootgitlab:~# wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/9/gitlab-ce-17.4.0-ce.0.el9.x86_64.rpm二.執行安裝腳本 2.1 先執行安裝前的命令 rootgitlab:~# apt install -y perl-interpreter rootgitlab:~# apt install -y openssh-s…

Cisco ASA防火墻查看ACL的條目數量

這里顯示的條目數量為ACE, ACE是啥&#xff1f; ACE全稱&#xff1a; access-list entry ACE指的是ACL條目展開后的數量&#xff0c; 啥叫展開&#xff1f; 示例&#xff1a; access-list out-in extend permit tcp80&443 host 1.1.1.1 host 2.2.2.2這種配置是占1條&#…

npm install安裝的node_modules是什么

node_modules 是一個由 npm&#xff08;Node Package Manager&#xff09;管理的文件夾&#xff0c;存放著你的 Node.js 項目中所有安裝的依賴包。當你運行 npm install 時&#xff0c;npm 會根據你的項目中 package.json 文件中的依賴配置&#xff0c;下載并安裝相應的包到 no…

【實時Linux實戰系列】實時Linux項目的部署與維護

在實時 Linux 項目的開發過程中&#xff0c;開發階段的工作僅僅是開始&#xff0c;生產環境中的部署與維護同樣至關重要。實時 Linux 系統廣泛應用于工業自動化、航空航天、智能交通等對實時性和穩定性要求極高的領域。例如&#xff0c;在工業自動化中&#xff0c;實時系統的部…

Go并發模式精要:掌握Goroutine與Channel的實戰藝術

在現代軟件開發中&#xff0c;有效利用并發能力已成為提升系統性能的關鍵。Go語言憑借其原生的Goroutine和Channel機制&#xff0c;為開發者提供了優雅的并發解決方案。本文將深入解析Go并發編程的核心模式與最佳實踐。 一、并發基石&#xff1a;Goroutine與Channel // 輕量級…

第29篇:Linux審計系統深度解析:基于OpenEuler 24.03的實踐指南

Linux審計系統深度解析&#xff1a;基于OpenEuler 24.03的實踐指南 文章目錄 Linux審計系統深度解析&#xff1a;基于OpenEuler 24.03的實踐指南一、Linux審計系統核心概念與組件架構1.1 審計系統核心組件詳解1. auditd守護進程&#xff1a;日志持久化引擎2. auditctl命令行工具…

Linux 啟動過程流程圖--ARM版

以下是ARM版本Linux啟動過程的超詳細樹狀圖&#xff0c;涵蓋硬件上電到應用程序交互的全流程&#xff0c;并包含關鍵函數調用鏈及源碼位置&#xff0c;適用于系統開發與調試場景&#xff1a; ARM Linux啟動全流程&#xff08;含函數調用鏈&#xff09; ARM Linux啟動流程&…

NVMe高速傳輸之擺脫XDMA設計6之系統架構設計

結合目前應用需求&#xff0c;以及前面基礎分析&#xff0c;確定IP應具有如下特色&#xff1a; &#xff08;1&#xff09; 通用性 前端數據采集系統基于 FPGA 開發。 一方面&#xff0c; 設備類型多&#xff0c; 使用的 FPGA型號各不相同&#xff0c; 需要實現的設計能夠在多種…

Mac homebrew 安裝教程

下載github安裝包 https://github.com/Homebrew/brew/releases/tag/4.5.8 下載安裝后 打開 安全里面允許安裝&#xff0c;就可以直接使用了

stm32hal模塊驅動(1)hpdl1414驅動

之前一直想用hpdl1414畫一塊手表&#xff0c;前面pcb測試板畫完沒空調試&#xff0c;最近剛好空出來時間&#xff0c;遂發下驅動。 這里簡單贅述hpdl1414的驅動原理&#xff1a;D0-D6負責數據輸入&#xff08;ascii表后7位&#xff09;&#xff0c;A0,A1負責更改hpdl1414模塊顯…

從代碼學習深度強化學習 - TRPO PyTorch版

文章目錄 前言核心工具函數廣義優勢估計 (Generalized Advantage Estimation, GAE)案例一:TRPO 解決離散動作問題 (CartPole-v1)1. 環境初始化2. 網絡結構定義3. TRPO 智能體實現4. 訓練與可視化5. 訓練主程序與結果案例二:TRPO 解決連續動作問題 (Pendulum-v1)1. 環境與工具…

MySQL 升級到8.4版本的詳細指南

本指南詳細介紹了將 MySQL 升級到 8.4 版本的完整流程、注意事項和操作方法。 一、升級前準備 (3.1 Before You Begin) 在開始升級之前&#xff0c;必須仔細審閱本節信息并執行所有推薦的操作&#xff1a; 理解升級過程&#xff1a;了解升級期間可能發生的情況。請參閱第 3.4…

leetcode427.建立四叉樹

區間x0到x1和區間y0到y1都是左閉右開的 解題基本思路是先判斷當前矩陣是不是全0或全1&#xff0c;如果是就直接返回新建的一個節點值(矩陣的統一值&#xff0c;葉子節點&#xff09;,如果不是那就新建一個節點值&#xff0c;非葉并且左上右上左下右下四個方向上遞歸創建節點 /…

醫學+AI教育實踐!南醫大探索數據挖掘人才培養,清華指導發布AI教育白皮書

教育數字化浪潮正以前所未有的力度重塑高等教育格局。今年4月&#xff0c;為貫徹落實《教育強國建設規劃綱要&#xff08;2024—2035 年&#xff09;》&#xff0c;教育部等九部門印發《關于加快推進教育數字化的意見》&#xff0c;表明將持續推動“人工智能教育”全方位發展&a…

PDF處理控件Spire.PDF系列教程:如何使用C# 拆分 PDF 文件(完整指南)

PDF文件因其高度的跨平臺兼容性和安全穩定的格式特點&#xff0c;廣泛應用于企業文檔管理和電子資料傳輸中。隨著PDF文檔頁數和內容復雜度的增加&#xff0c;拆分PDF成為優化文檔處理流程、提升辦公效率的重要需求。通過編程方式實現PDF拆分&#xff0c;不僅能自動化處理海量文…

文心4.5開源模型部署實踐

文心4.5開源模型部署實踐 使用fastdeploy本地部署 執行命令&#xff1a; python -m fastdeploy.entrypoints.openai.api_server \--model baidu/ERNIE-4.5-21B-A3B-Paddle \--port 8180 \--metrics-port 8181 \--engine-worker-queue-port 8182 \--max-model-len 32768 \--m…

Python迭代器、生成器、閉包和裝飾器(三器一包)

return、continue、break區別&#xff1a; return只能用在函數里面&#xff0c;表示從函數中返回&#xff0c;函數體內的后續任何代碼都不執行continue只是跳出當前循環&#xff0c;進入下一循環break只是跳出全部循環&#xff0c;如果循環后面還有代碼&#xff0c;會進行執行…

【Java】Maven

一.Maven簡介 Maven的產生主要是為了解決Java項目中的兩個問題&#xff1a; 1.依賴管理&#xff1a; 傳統 Java 項目在引入第三方庫時&#xff0c;需要手動下載 JAR 包并維護復雜的依賴關系。Maven 提供了統一的依賴管理機制&#xff0c;通過簡單的配置即可自動從倉庫下載并引…