生产者消费者问题例题及详解

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

生产者消费者问题例题及详解

生产者消费者问题是一个经典的并发问题,涉及到两个独立的线程:生产者和消费者。生产者生产物品,消费者消费物品。生产者、消费者共享一个公共的固定大小的缓冲区。

以下是一个简单的生产者消费者问题的例子:

假设有一个固定大小的缓冲区,大小为N。生产者负责生成数据放入缓冲区,而消费者负责从缓冲区取出数据并处理。

1. 当缓冲区为空时,消费者被阻塞,等待生产者生产数据。

2. 当缓冲区满时,生产者被阻塞,等待消费者消费数据。

3. 缓冲区的每个元素只能被消费一次。

4. 缓冲区是循环使用的,即当缓冲区的最后一个元素被消费后,下一个元素将是缓冲区的第一个元素。

问题:如何实现这个生产者消费者模型?

解答:可以使用条件变量和互斥锁来实现这个模型。

首先,定义一个缓冲区数组和一个计数器变量来跟踪缓冲区的使用情况。然后,定义两个条件变量:一个用于生产者等待缓冲区非空,另一个用于消费者等待缓冲区非空。最后,使用互斥锁来保护对缓冲区和计数器的访问。

以下是使用C++实现的代码示例:

```cpp

include

include

include

include

const int N = 5; // 缓冲区大小

int buffer[N]; // 缓冲区数组

int count = 0; // 计数器变量,表示缓冲区的使用情况

std::mutex mutex; // 互斥锁

std::condition_variable cv_prod; // 生产者等待条件变量

std::condition_variable cv_cons; // 消费者等待条件变量

void producer() {

for (int i = 0; i < N 2; i++) {

std::unique_lock lock(mutex);

cv_(lock, []{ return count < N; }); // 等待缓冲区非空

buffer[count] = i; // 生产数据放入缓冲区

std::cout << "Producer produced " << i << std::endl;

count++; // 更新计数器变量

if (count == N) count = 0; // 循环使用缓冲区

cv__one(); // 通知消费者消费数据

}

}

void consumer() {

for (int i = 0; i < N 2; i++) {

std::unique_lock lock(mutex);

cv_(lock, []{ return count > 0; }); // 等待缓冲区非空

int data = buffer[count]; // 从缓冲区取出数据并处理 std::cout << "Consumer consumed " << data << std::endl;

count--; // 更新计数器变量

if (count == -1) count = N - 1; // 循环使用缓冲区

cv__one(); // 通知生产者生产数据

}

}

int main() {

std::thread prod(producer); // 创建生产者线程 std::thread cons(consumer); // 创建消费者线程 (); // 等待生产者线程结束

(); // 等待消费者线程结束

return 0;

}

```

相关文档
最新文档