C++中notify機(jī)制是如何實(shí)現(xiàn)的

c++
小樊
93
2024-08-29 07:23:22

在 C++ 中,std::condition_variable 類提供了一種條件變量,可以用于線程間的同步。它常與 std::mutexstd::unique_lockstd::lock_guard 結(jié)合使用。

當(dāng)一個(gè)線程需要等待另一個(gè)線程完成某個(gè)操作時(shí),可以使用條件變量。這里有兩個(gè)主要的函數(shù):wait()notify_one() / notify_all()。

  1. wait(): 當(dāng)一個(gè)線程調(diào)用 cond_var.wait(lock, [&](){ return condition; }) 時(shí),該線程會(huì)釋放鎖并等待條件變量 cond_var 被通知。一旦收到通知,線程將重新獲取鎖并檢查條件是否滿足。如果條件滿足,則繼續(xù)執(zhí)行;否則,線程將再次等待通知。
  2. notify_one() / notify_all(): 當(dāng)另一個(gè)線程完成操作并更改條件時(shí),它可以調(diào)用 cond_var.notify_one()cond_var.notify_all() 來(lái)通知等待的線程。notify_one() 只喚醒一個(gè)等待的線程,而 notify_all() 喚醒所有等待的線程。

下面是一個(gè)簡(jiǎn)單的示例,展示了如何使用條件變量實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者模型:

#include<iostream>
#include<thread>
#include<queue>
#include <mutex>
#include<condition_variable>

std::queue<int> data_queue;
std::mutex mtx;
std::condition_variable cond_var;
const int max_queue_size = 5;

void producer() {
    for (int i = 0; i < 20; ++i) {
        std::unique_lock<std::mutex> lock(mtx);
        cond_var.wait(lock, [] { return data_queue.size() < max_queue_size; }); // 等待隊(duì)列未滿
        data_queue.push(i);
        std::cout << "Produced: " << i << std::endl;
        lock.unlock();
        cond_var.notify_one(); // 通知消費(fèi)者
    }
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        cond_var.wait(lock, [] { return !data_queue.empty(); }); // 等待隊(duì)列非空
        if (data_queue.front() == 19) break; // 特殊情況:生產(chǎn)者已完成生產(chǎn)
        int value = data_queue.front();
        data_queue.pop();
        std::cout << "Consumed: "<< value<< std::endl;
        lock.unlock();
        cond_var.notify_one(); // 通知生產(chǎn)者
    }
}

int main() {
    std::thread prod(producer);
    std::thread cons(consumer);

    prod.join();
    cons.join();

    return 0;
}

在這個(gè)示例中,我們使用條件變量 cond_var 在生產(chǎn)者和消費(fèi)者線程之間進(jìn)行同步。生產(chǎn)者線程在隊(duì)列未滿時(shí)生產(chǎn)數(shù)據(jù),并通知消費(fèi)者線程。消費(fèi)者線程在隊(duì)列非空時(shí)消費(fèi)數(shù)據(jù),并通知生產(chǎn)者線程。

0