c++11 producer and customer design

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

std::mutex mut;
std::mutex ful;
std::queue<int> data_queue;
std::condition_variable data_cond;
std::condition_variable data_full;
std::default_random_engine e(time(0));
std::uniform_int_distribution<int> dis(1,5);

#define MAX_QUEUE_SIZE 10
int cur_num = 0;

void provider() {
    while (true) {
        if (cur_num < MAX_QUEUE_SIZE) {
            int num = cur_num;
            std::this_thread::sleep_for(std::chrono::seconds(dis(e)));
            std::lock_guard<std::mutex> lk(mut);
            data_queue.push(num);
            cur_num++;
            std::cout << "produce next one: " << data_queue.size() << std::endl;
            data_cond.notify_one();
        } else {
            std::unique_lock<std::mutex> lk(ful);
            data_full.wait(lk,[]{ return data_queue().size < MAX_QUEUE_SIZE ;});
            std::cout << "it's time to produce next one: " << data_queue.size() << std::endl;
        }   
    }   
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk,[]{ return !data_queue.empty(); });
        int num = data_queue.front();
        data_queue.pop();
        cur_num--;
        lk.unlock();

        std::cout << "eat num: " << num << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(dis(e)));
        std::lock_guard<std::mutex> full_mutex(ful);
        data_full.notify_one();
    }
}

int main() {
    std::thread t1(provider);
    std::thread t2(consumer);

    t1.join();
    t2.join();

    return 0;
}


modified it by RAII of C++, let's write another struct: threadsafe_queue demo:

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

template <typename T>
class threadsafe_queue {
private:
    mutable std::mutex mut;
    std::queue<T> data_queue;
    std::condition_variable data_cond;

public:
    threadsafe_queue() {}
    threadsafe_queue(threadsafe_queue const& other) {
        std::lock_guard<std::mutex> lk(other.mut);
        data_queue = other.data_queue;
    }   

    void push(T new_value) {
        std::lock_guard<std::mutex> lk(mut);
        data_queue.push(new_value);
        data_cond.notify_one();
    }   

    void wait_and_pop(T& value) {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this]{ return !data_queue.empty(); }); 
        value = data_queue.front();
        data_queue.pop();
    }   

    std::shared_ptr<T> wait_and_pop() {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this] { return !data_queue.empty(); }); 
        std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
        data_queue.pop();
        return res;
    }   
    
    bool try_pop(T& value) {
        std::lock_guard<std::mutex> lk(mut);
        if (data_queue.empty())
            return false;

        value = data_queue.front();
        data_queue.pop();
        return true;
    }

    std::shared_ptr<T> try_pop() {
        std::lock_guard<std::mutex> lk(mut);
        if (data_queue.empty())
            return std::shared_ptr<T>();
        std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
        data_queue.pop();
        return res;
    }

    bool empty() const {
        std::lock_guard<std::mutex> lk(mut);
        return data_queue.empty();
    }
};

threadsafe_queue<int> queue;

int num;
void producer() {
    while(true) {
        std::cout << "producer: " << num << std::endl;
        queue.push(++num);
    }
}

void consumer() {
    while (true) {
        std::shared_ptr<int> num = queue.wait_and_pop();
        std::cout << "consumer: " << *num << std::endl;
    }
}

int main() {
    std::thread t1(producer);
    std::thread t2(consumer);

    t1.join();
    t2.join();

    return 0;

}

 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值