C++boost线程唤醒

26 篇文章 1 订阅

在这个示例中,我们创建了一个生产者线程和一个消费者线程。生产者每秒生产一个数字,然后通过condition.notify_one()
通知消费者线程数据已经准备好。消费者则等待数据准备好的通知,收到通知后输出并消费数据。整个过程共进行了5次生产和消费。
condition.notify_one()函数用于通知一个等待在条件变量上的线程。它会唤醒一个等待的线程,使其从等待状态返回到可运行状态。

在本例中,生产者线程在每次生产新数据后会调用condition.notify_one()来通知消费者线程有新的数据可供消费。即使有多个消费者线程在等待,notify_one也只会唤醒其中的一个线程,而不是所有线程都唤醒。

这样可以确保只有一个消费者线程会被唤醒来消费新的数据,从而避免多个线程同时访问和处理同一份数据,确保线程安全。

#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>

boost::mutex mutex;
boost::condition_variable condition;
int sharedData = 0;

void producer() {
    for (int i = 0; i < 5; ++i) {
        boost::this_thread::sleep_for(boost::chrono::seconds(1));
        {
            boost::lock_guard<boost::mutex> lock(mutex);
            sharedData = i;
            std::cout << "Producer produced: " << i << std::endl;
        }
        condition.notify_one();
    }
}

void consumer() {
    for (int i = 0; i < 5; ++i) {
        boost::unique_lock<boost::mutex> lock(mutex);
        condition.wait(lock);//, []{ return sharedData != 0; });
        std::cout << "Consumer consumed: " << sharedData << std::endl;
        sharedData = 0;
        lock.unlock();
    }
}

int main() {
    // Create producer and consumer threads
    boost::thread producerThread(producer);
    boost::thread consumerThread(consumer);
    
    // Wait for the threads to finish
    producerThread.join();
    consumerThread.join();

    return 0;
}
/*
在这个示例中,我们创建了一个生产者线程和一个消费者线程。生产者每秒生产一个数字,然后通过`condition.notify_one()`
通知消费者线程数据已经准备好。消费者则等待数据准备好的通知,收到通知后输出并消费数据。整个过程共进行了5次生产和消费。
*/

这段代码是在调用condition.wait()函数时,使用了一个lambda表达式作为条件,具体含义如下:

  1. lock是要传递的锁对象,这里是mutex锁。
  2. []{ return sharedData != 0; }是lambda表达式,它定义了一个条件,即当sharedData不等于0时返回true,此时condition.wait()函数会等待,否则会继续执行。lambda表达式作为条件用于判断等待的条件是否成立。
  3. 因此,condition.wait(lock, []{ return sharedData != 0; })这行代码的含义是:线程等待条件变量sharedData满足条件sharedData !=0才会继续执行,否则会一直等待。

在这个例子中,消费者线程在执行condition.wait(lock, []{ return sharedData != 0; })时,会等待生产者线程通知条件变量sharedData已经不为0,即有新数据可供消费。这样可以保证消费者线程只有在新的数据产生时才会执行消费操作。

执行结果:

Producer produced: 0
Consumer consumed: 0
Producer produced: 1
Consumer consumed: 1
Producer produced: 2
Consumer consumed: 2
Producer produced: 3
Consumer consumed: 3
Producer produced: 4
Consumer consumed: 4

如果去掉了生产者线程中的sleep_for函数,消费者线程将无法正确运行的原因是,生产者线程可能会在很短的时间内非常快速地生产出数据,然后立即通知消费者线程。而消费者线程可能在收到通知后还没有开始等待条件变量的唤醒,便已经错过了通知,导致消费者线程错失了处理新数据的机会。

消费者线程在调用condition.wait()时,如果在调用前就发生了notify_one()的通知,那么condition.wait()将不会等待,而是直接返回继续执行。所以,如果生产者生产数据的速度非常快,可能会导致消费者错失通知,无法及时处理新数据。

因此,在实际应用中,生产者生产数据的速度和消费者消费数据的速度需要协调合适,以确保生产者和消费者之间的通信和数据处理能够正确进行。

#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>

boost::mutex mutex;
boost::condition_variable condition;
int pay = 0;

void customerPurchase()
{
     for(int i = 0;i < 10;i++){
           boost::this_thread::sleep_for(boost::chrono::seconds(1));
           boost::lock_guard<boost::mutex> lock(mutex);
          // pay = i;
           std::cout << "customer Purchase: " << i << " " << "RMB" << std::endl;
           condition.notify_one();
     }
      
}

void PurchaseCOnfirm()
{
    for(int i = 0;i<10;i++){
        boost::unique_lock<boost::mutex> lock(mutex);
        condition.wait(lock);//, []{ return sharedData != 0; });
        std::cout << "Customer COnfirm: " << i << std::endl;
        lock.unlock(); 

    }

}


int main() {
    // Create producer and consumer threads
    boost::thread purchaseThread(customerPurchase);
    boost::thread purchaseCOnfirmThread(PurchaseCOnfirm);
    
    // Wait for the threads to finish
    purchaseThread.join();
    purchaseCOnfirmThread.join();

    return 0;
}
  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack Ju

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值