21xrx.com
2024-12-22 22:16:42 Sunday
登录
文章检索 我的文章 写文章
C++实现生产者消费者模式
2023-07-03 14:14:24 深夜i     --     --
C++ 生产者消费者模式 实现

生产者消费者模式是一种常见的多线程设计模式,它通过使用一个共享的缓冲区来解决生产者与消费者之间的同步和通信问题,从而实现线程之间的协作。C++语言提供了多种实现多线程的方式,例如POSIX线程、Windows API、Qt、Boost库等等,这些方式都可以用来实现生产者消费者模式。

下面介绍一种基于POSIX线程的实现方式。首先需要定义一个结构体作为缓冲区,并定义两个指针成员front和rear分别指向缓冲区队首和队尾,以及一个互斥锁和两个条件变量。互斥锁用来保证同时只有一个线程可以访问缓冲区,条件变量用来唤醒等待在缓冲区上的线程。


struct Buffer {

  int size; // 缓冲区大小

  int *data; // 缓冲区数据

  int front; // 缓冲区队首指针

  int rear; // 缓冲区队尾指针

  pthread_mutex_t mutex; // 互斥锁

  pthread_cond_t not_empty; // 非空条件变量

  pthread_cond_t not_full; // 非满条件变量

};

然后定义两个线程函数作为生产者和消费者,分别在缓冲区中生产和消费数据。生产者线程首先尝试获取缓冲区的互斥锁,然后检查缓冲区是否已满,如果满了则等待非满条件变量被唤醒,否则将数据写入缓冲区,并更新队尾指针。最后释放互斥锁并唤醒等待在非空条件变量上的线程。


void *producer(void *arg) {

  Buffer *buf = (Buffer*) arg;

  while (true) {

    pthread_mutex_lock(&buf->mutex);

    while (buf->rear == buf->front - 1 || (buf->rear == buf->size - 1 && buf->front == 0)) {

      pthread_cond_wait(&buf->not_full, &buf->mutex);

    }

    int data = rand() % 100;

    buf->data[buf->rear] = data;

    buf->rear = (buf->rear + 1) % buf->size;

    pthread_mutex_unlock(&buf->mutex);

    pthread_cond_signal(&buf->not_empty);

  }

  return NULL;

}

消费者线程也类似地尝试获取缓冲区的互斥锁,然后检查缓冲区是否为空,如果为空则等待非空条件变量被唤醒,否则将数据从缓冲区中读出,并更新队首指针。最后释放互斥锁并唤醒等待在非满条件变量上的线程。


void *consumer(void *arg) {

  Buffer *buf = (Buffer*) arg;

  while (true) {

    pthread_mutex_lock(&buf->mutex);

    while (buf->front == buf->rear) {

      pthread_cond_wait(&buf->not_empty, &buf->mutex);

    }

    int data = buf->data[buf->front];

    buf->front = (buf->front + 1) % buf->size;

    pthread_mutex_unlock(&buf->mutex);

    pthread_cond_signal(&buf->not_full);

    printf("consumed %d\n", data);

  }

  return NULL;

}

最后在main函数中创建生产者和消费者线程,并等待它们结束。


int main() {

  Buffer buf = { 100, new int[100], 0, 0 };

  pthread_mutex_init(&buf.mutex, NULL);

  pthread_cond_init(&buf.not_empty, NULL);

  pthread_cond_init(&buf.not_full, NULL);

  pthread_t t1, t2;

  pthread_create(&t1, NULL, producer, &buf);

  pthread_create(&t2, NULL, consumer, &buf);

  pthread_join(t1, NULL);

  pthread_join(t2, NULL);

  return 0;

}

这样就完成了生产者消费者模式的实现。需要注意的是,该实现方式对于数据类型、存储方式等都有一定的限制,具体实现的细节还需要进一步优化和完善。

  
  

评论区

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