117.info
人生若只如初见

C++中notify机制是如何实现的

在 C++ 中,std::condition_variable 类提供了一种条件变量,可以用于线程间的同步。它常与 std::mutexstd::unique_lockstd::lock_guard 结合使用。

当一个线程需要等待另一个线程完成某个操作时,可以使用条件变量。这里有两个主要的函数:wait()notify_one() / notify_all()

  1. wait(): 当一个线程调用 cond_var.wait(lock, [&](){ return condition; }) 时,该线程会释放锁并等待条件变量 cond_var 被通知。一旦收到通知,线程将重新获取锁并检查条件是否满足。如果条件满足,则继续执行;否则,线程将再次等待通知。
  2. notify_one() / notify_all(): 当另一个线程完成操作并更改条件时,它可以调用 cond_var.notify_one()cond_var.notify_all() 来通知等待的线程。notify_one() 只唤醒一个等待的线程,而 notify_all() 唤醒所有等待的线程。

下面是一个简单的示例,展示了如何使用条件变量实现生产者-消费者模型:

#include
#include
#include
#include 
#include

std::queue 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 lock(mtx);
        cond_var.wait(lock, [] { return data_queue.size() < max_queue_size; }); // 等待队列未满
        data_queue.push(i);
        std::cout << "Produced: " << i << std::endl;
        lock.unlock();
        cond_var.notify_one(); // 通知消费者
    }
}

void consumer() {
    while (true) {
        std::unique_lock lock(mtx);
        cond_var.wait(lock, [] { return !data_queue.empty(); }); // 等待队列非空
        if (data_queue.front() == 19) break; // 特殊情况:生产者已完成生产
        int value = https://www.yisu.com/ask/data_queue.front();"Consumed: "<< value<< std::endl;
        lock.unlock();
        cond_var.notify_one(); // 通知生产者
    }
}

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

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

    return 0;
}

在这个示例中,我们使用条件变量 cond_var 在生产者和消费者线程之间进行同步。生产者线程在队列未满时生产数据,并通知消费者线程。消费者线程在队列非空时消费数据,并通知生产者线程。

未经允许不得转载 » 本文链接:https://www.117.info/ask/fe516AzsBAgNVAw.html

推荐文章

  • atoi函数在C++中的最佳实践

    在C++中,通常使用std::stoi函数来将字符串转换为整数。std::stoi函数是标准库中的函数,它接受一个字符串参数,并返回对应的整数值。使用std::stoi函数可以实现...

  • C++中如何安全地使用atoi

    在C++中,可以使用stoi函数来安全地将字符串转换为整数。stoi函数会检查转换过程中是否出现了非数字字符,如果出现了非数字字符,会抛出invalid_argument异常。以...

  • 使用atoi转换时C++应注意什么

    在使用atoi函数进行字符串转换时,需要注意以下几点: 输入字符串必须是以数字开头,否则会返回0。
    输入字符串中只能包含数字字符和可选的正负号字符,否则...

  • C++下atoi与stoi的区别

    atoi和stoi都是用来将字符串转换为整数的函数,但它们之间有一些区别: atoi是一个C语言标准库函数,需要包含头文件,而stoi是C++11引入的标准库函数,需要包含头...

  • vi命令在Ubuntu中的学习路径推荐

    在Ubuntu中学习vi命令,首先需要了解vi编辑器的基本操作和命令,然后可以通过配置vi编辑器来提高编辑效率。以下是一些学习路径和资源推荐:
    学习路径 基本操...

  • Bootstrap spinner在表单验证中的应用

    Bootstrap 是一个流行的前端框架,它提供了一系列预定义的样式和组件,可以帮助开发者快速构建美观、响应式的网页。Bootstrap Spinner 是其中一个组件,用于显示...

  • 如何自定义Bootstrap spinner的样式

    要自定义 Bootstrap 的 spinner 样式,您可以按照以下步骤操作: 首先,在 HTML 文件中创建一个基本的 Bootstrap spinner。这是一个使用 Bootstrap 5 的示例: C...

  • Bootstrap spinner的常见用法有哪些

    Bootstrap 是一个流行的前端框架,它提供了一系列预定义的样式和组件,用于快速构建网页 按钮加载状态:当用户点击按钮时,可以在按钮内显示一个 spinner,表示正...