c++11 producer and customer design

来源:互联网 发布:mac wine下载安装 编辑:程序博客网 时间:2024/05/16 18:33
#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 10int 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 0
原创粉丝点击