赞
踩
生产者每次生产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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。