C++多线程例题-生产者和消费者问题

        生产者每次生产1个随机整数,放到缓冲区中;消费者每次从缓冲区中按生产顺序取出1个整数。每次缓冲区发生变化,打印放入/取出的数,以及缓冲当前大小。

        情形1:初始为空,生产速率2/秒,消费速率1/秒

        情形2:初始全满,生产速率1/秒,消费速率2/秒

        情形3:初始半满,生产速率=消费速率

参考这个博客进行了一些改动

三个输入参数分别是当前的buffer中item的数量,生产者生产速率,消费者消费速率。

#include <mutex>
#include <condition_variable>
#include <windows.h>
#include <thread>
#include<iostream>

using namespace std;

static const int buffer_size = 128; // 缓存大小
static const int item_total = 300;  //总共要生产 item_total个item
int produce_num = 1;
int consume_num = 1;

// 缓存结构体, 使用循环队列当做缓存
struct Buffer
{
    int buffer[buffer_size];
    size_t read_position;  // 当前读位置
    size_t write_position; // 当前写位置
    mutex mtx;             // 读写互斥
    //条件变量
    condition_variable not_full;
    condition_variable not_empty;
} buffer_res;

typedef struct Buffer Buffer;

int get_write_position(Buffer *b)
{
    for (int i = 0; i < buffer_size; i++)
    {
        if (0 == b->buffer[i])
        {
            return i;
        }
    }
    return buffer_size;
}

int get_read_position(Buffer *b)
{
    for (int i = 0; i < buffer_size; i++)
    {
        if (0 != b->buffer[i])
        {
            return i;
        }
    }
    return buffer_size;
}

void porduce_item(Buffer *b)
{
    unique_lock<mutex> lock(b->mtx); //设置互斥锁
    while (1)
    {
        b->write_position = get_write_position(b);
        if (b->write_position == buffer_size)
        {
            //当前缓存已经满了
            cout << "buffer is full now, producer is wating....." << endl;
            (b->not_full).wait(lock); // 等待缓存非full
        }
        else
        {
            break;
        }
    }
    int item = rand() % buffer_size + 1;
    cout << "produce item: " << item << " in " << b->write_position << " ***" << endl;
    // 向缓存中添加item
    (b->buffer)[b->write_position] = item;

    (b->not_empty).notify_all();
    lock.unlock();
}

int consume_item(Buffer *b)
{
    unique_lock<mutex> lock(b->mtx);
    while (1)
    {
        b->read_position = get_read_position(b);
        if (b->read_position == buffer_size)
        {
            // 当前buffer 为空
            cout << "buffer is empty , consumer is waiting....." << endl;
            (b->not_empty).wait(lock);
        }
        else
        {
            break;
        }
    }
    int item = (b->buffer)[b->read_position];
    (b->buffer)[b->read_position] = 0;
    cout << "consume item: " << item << " in " << b->read_position << endl;

    (b->not_full).notify_all();
    lock.unlock();

    return item;
}

//生产者任务
void producer(int buf)
{
    for (int i = 1; i <= item_total - buf; i++)
    {
        //生产item需要的时间
        Sleep(20 / produce_num);
        porduce_item(&buffer_res);
    }
}

//消费者任务
void consumer()
{
    static int cnt = 0;
    while (1)
    {
        //消费需要的时间
        Sleep(20 / consume_num);
        int item = consume_item(&buffer_res);
        if (++cnt == item_total)
            break;
    }
}

//初始化 buffer, buf空满状态,p_num为produce_num, c_num为consume_num
void init_buffer(Buffer *b, const int buf)
{
    for (int i = 0; i < buf; i++)
    {
        b->buffer[i] = rand() % buffer_size + 1;
    }
    for (int i = buf; i < buffer_size; i++)
    {
        b->buffer[i] = 0;
    }
}

int main(int argc, char **argv)
{
    int buf = 0;
    if (argc >= 4)
    {
        buf = atoi(argv[1]);
        produce_num = atoi(argv[2]);
        consume_num = atoi(argv[3]);
    }
    else
    {
        cout << "Please enter the initial buffer items, "
                "produce_num ∈ {1,2} and consume_num ∈ {1,2}."
             << endl;
        cin >> buf >> produce_num >> consume_num;
    }

    init_buffer(&buffer_res, buf);
    thread produce(producer, buf);
    thread consume(consumer);
    produce.join();
    consume.join();
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值