C++ while循环 vs condition_variable

22 篇文章 0 订阅

消费者线程等待生产者发来的信息

第一版 while + sleep

while (true)
{
    if (is_sent_)
    {
        is_sent_ = false;
        //Do something ...
    }
    // Sleep this thread for 5 MilliSeconds
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
}

总感觉sleep是很傻的行为,sleep(0) 还是sleep(10) ?貌似window平台最小精度为15ms

改进的方案 ,用C++ 11的condition_variable

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

std::queue<int> dataQueue;
std::mutex queueMutex;
std::condition_variable queueConditionVariable;

void producerFunction() {
    // This function will keep generating data forever
    int sleepSeconds;
    int newNumber;
    while (true) {
        // Wait from 1 to 3 seconds before generating data
        sleepSeconds = rand() % 3 + 1;
        std::this_thread::sleep_for(std::chrono::seconds(sleepSeconds));

        // Add a number to the queue
        newNumber = rand() % 100 + 1; // Random number from 1 to 100
        std::lock_guard<std::mutex> g(queueMutex);
        dataQueue.push(newNumber);

        std::cout << "Added number to queue: " << newNumber << std::endl;

        // Notify one thread that the condition variable might have changed. Notice
        // the notification is sent while still holding the lock
        queueConditionVariable.notify_one();
    }
}

void consumerFunction() {
    // This function will consume data forever
    while (true) {
        int numberToProcess = 0;

        // We only need to lock the mutex for the time it takes us to pop an item
        // out. Adding this scope releases the lock right after we poped the item
        {
            // Condition variables need a unique_lock instead of a lock_guard because
            // the mutex might be locked and unlocked multiple times. Creating the
            // unique_lock like this, locks the mutex
            std::unique_lock<std::mutex> g(queueMutex);

            // This call to `wait` will first check if the contion is met. i.e. If
            // the queue is not empty.
            // If the queue is not empty, the execution of the code will continue
            // If the queue is empty, it will unlock the mutex and wait until a signal
            // is sent to the condition variable. When the signal is sent, it will
            // acquire the lock and check the condition again.
            queueConditionVariable.wait(g, [] { return !dataQueue.empty(); });

            // We don't need to check if the queue is empty anymore, because the
            // Condition Variable does that for us
            numberToProcess = dataQueue.front();
            dataQueue.pop();
        }

        // Only process if there are numbers
        if (numberToProcess) {
            std::cout << "Processing number: " << numberToProcess << std::endl;
        }
    }
}

int main() {
    std::thread producer(producerFunction);
    std::thread consumer1(consumerFunction);

    producer.join();
    consumer1.join();
}

运行结果:

root@ubuntu:/app/boost/example/condition# g++ condition.cpp -o condition -lpthread
root@ubuntu:/app/boost/example/condition# ./condition
Added number to queue: 87
Processing number: 87
Added number to queue: 16
Processing number: 16
Added number to queue: 36
Processing number: 36
Added number to queue: 93
Processing number: 93
Added number to queue: 22
Processing number: 22
Added number to queue: 28
Processing number: 28

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值