21xrx.com
2024-11-22 05:46:23 Friday
登录
文章检索 我的文章 写文章
C++编程实现生产者消费者模式
2023-07-10 17:56:41 深夜i     --     --
C++编程 生产者消费者模式 多线程编程 互斥锁 条件变量

生产者消费者模式(Producer-Consumer Pattern)是一种常见的多线程编程模式,用于解决在生产者和消费者之间的数据交互问题。在这种模式中,生产者线程负责产生数据并放入缓冲区中,而消费者线程则从缓冲区中取出数据并进行处理。这种模式可以避免线程之间的竞争和死锁问题,因此在实际应用中广泛使用。

在C++中,可以通过条件变量和互斥锁来实现生产者消费者模式。具体实现流程如下:

1. 定义缓冲区

首先定义一个缓冲区类,该类中包含一个互斥锁和两个条件变量。缓冲区的大小可以通过构造函数进行设置。


class Buffer

{

public:

  Buffer(int size) : size_(size), count_(0), in_(0), out_(0)

  {

    buffer_ = new int[size];

  }

  ~Buffer()

  {

    delete[] buffer_;

  }

  void produce(int value)

  {

    std::unique_lock<std::mutex> lock(mutex_);

    while (count_ == size_)

    {

      full_.wait(lock);

    }

    buffer_[in_] = value;

    in_ = (in_ + 1) % size_;

    ++count_;

    empty_.notify_all();

  }

  int consume()

  {

    std::unique_lock<std::mutex> lock(mutex_);

    while (count_ == 0)

    {

      empty_.wait(lock);

    }

    int value = buffer_[out_];

    out_ = (out_ + 1) % size_;

    --count_;

    full_.notify_all();

    return value;

  }

private:

  int size_;

  int count_;

  int in_;

  int out_;

  int* buffer_;

  std::mutex mutex_;

  std::condition_variable empty_;

  std::condition_variable full_;

};

2. 实现生产者和消费者线程

在生产者线程中,用一个循环来不断调用缓冲区的produce方法,向缓冲区中添加数据。在消费者线程中,也用一个循环来不断调用缓冲区的consume方法,从缓冲区中取出数据进行处理。


void producer(Buffer& buffer)

{

  for (int i = 0; i < 10; ++i)

  {

    buffer.produce(i);

    std::this_thread::sleep_for(std::chrono::milliseconds(100));

  }

}

void consumer(Buffer& buffer)

{

  for (int i = 0; i < 10; ++i)

  {

    int value = buffer.consume();

    std::cout << value << std::endl;

    std::this_thread::sleep_for(std::chrono::milliseconds(100));

  }

}

3. 启动线程并测试

最后,通过调用std::thread来启动生产者和消费者线程,并等待线程的结束。


int main()

{

  Buffer buffer(5);

  std::thread t1(producer, std::ref(buffer));

  std::thread t2(consumer, std::ref(buffer));

  t1.join();

  t2.join();

  return 0;

}

这是一种简单的生产者消费者模式实现方式,在实际应用中可能需要更复杂的设计和优化。但无论如何,掌握这种模式的基本原理和实现方法,对于编写高效、稳定的多线程应用是非常有帮助的。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复