用BlockBoundQueue和c++11实现多线程生产者消费者问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// file : blockBoundQueue.h
#ifndef YANG_BLOCKBOUNDQUEUE
#define YANG_BLOCKBOUNDQUEUE
#include <mutex>
#include <condition_variable>
#include <queue>
#include <cstdio>
namespace yang{
#define _FULL 4 //
template <typename _Tp>
class BlockBoundQueue
{
public:
    BlockBoundQueue(size_t bound = _FULL) :bound_(bound){}
    BlockBoundQueue(const BlockBoundQueue&) = delete;
    BlockBoundQueue& operator=(const BlockBoundQueue&) = delete;
    void push(const _Tp& value)
    {
        std::unique_lock<std::mutex> lck(mutex_);// 利用RAII技法,将mutex_托管给lck
        while (count_ + 1 == bound_)// 用while防止虚假唤醒
        {
            printf("the queue is full , waiting for the consumer consuming !\n");
            notFull_.wait(lck); //等待队列非满条件发生
        }
        count_++;
        queue_.push(value);
        notEmpty_.notify_one();//通知队列非空,不能用all,读者自行思考为什么
    }
    _Tp get()
    {
        std::unique_lock<std::mutex> lck(mutex_);
        while (queue_.empty())
        {
            printf("the queue is empty , waiting for the producer producing !\n");
            notEmpty_.wait(lck);//等待队列为非空
        }
        _Tp front(queue_.front());
        queue_.pop();
        count_--;
        notFull_.notify_one();//通知队列为非满,请注意不能用all
        return front;
    }
private:
    std::mutex mutex_;
    std::condition_variable notEmpty_;
    std::condition_variable notFull_;
    std::queue<_Tp> queue_;
    size_t count_{ 0 };
    size_t bound_;
};
}
#endif
//在visual studio 2013上编译运行通过

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// file : main.cpp
#include <cstdio>
#include <cstdlib>
#include <thread>
#include "BlockBoundQueue.h"
yang::BlockBoundQueue<int> blockboundqueue_;// 全局的缓冲边界队列
const int total = 16; // 商品总数
void consumer(size_t id,size_t n); // 消费者
void producer(size_t id,size_t n); // 生产者
int main()
{
    std::thread consumer1(consumer,0, 5);
    std::thread consumer2(consumer,1, 5);
    std::thread consumer3(consumer,2, 6);
    std::thread producer1(producer,0, 8);
    std::thread producer2(producer,1, 8);
    consumer1.join();
    consumer2.join();
    consumer3.join();
    producer1.join();
    producer2.join();
    system("pause");
    return 0;
}
void consumer(size_t id,size_t n)
{
    for (auto i = 0; i < n; ++i)
    {
        std::this_thread::sleep_for(std::chrono::seconds(2));
        int item = blockboundqueue_.get();
        printf("the %d^th consumer thread has consumed the %d^th item\n", id,item);
    }
}
 
void producer(size_t id,size_t n)
{
    for (int i = 0; i < n; ++i)
    {
        blockboundqueue_.push(i);
        printf("the %d^th producer thread has produced the %d^th item\n",id, i);
    }
}

【转】https://blog.csdn.net/dhz625/article/details/72026666

posted on   lydstory  阅读(227)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示