Linux条件变量和互斥锁实现生产者消费者问题

2022-02-25 08:34:05 浏览数 (1)

生产者消费者问题作为多线程多进程同步互斥的经典问题,值得思考。本文使用Linux系统调用,通过互斥锁和条件变量模拟生产者消费者问题。

代码语言:javascript复制
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

struct Node {
  int _val;
  Node *_next;
  Node(int val, Node *next):_val(val), _next(next) {}
};
pthread_mutex_t mtx;
pthread_cond_t cond;

Node *head=NULL; // 全局变量 为消费者和生产者的互斥共享资源


void* func1(void *arg) {
  while (1) {
    pthread_mutex_lock(&mtx);  // 涉及到访问临界区的访问都需要互斥锁保护
    if (!head) {   // head==NULL  缓冲区无内容可读
      // 阻塞当前线程 并对mutex进行解锁操作
      pthread_cond_wait(&cond, &mtx);
      // 生产者通知消费者消费后 接触阻塞 并对mutex进行加锁操作
    } 
    else {
      // 删除头节点
      Node *p = head;
      head = p->_next;
      printf("consumer: %lu thread, consume %dn", pthread_self(), p->_val);
      delete p;
      p = NULL;
    }
    pthread_mutex_unlock(&mtx);
  }
  return NULL;
}

void* func2(void *arg) {
  while (1) {
    pthread_mutex_lock(&mtx);
    Node* p = new Node(rand()0, head);
    head = p;
    printf("producer: %lu thread, produce %dn", pthread_self(), p->_val);
    pthread_mutex_unlock(&mtx);
    pthread_cond_signal(&cond);// 通知消费者线程缓冲区现在又内容可以读

    sleep(rand() % 3);
  }
  return NULL;
}



int main() {
  srand(time(NULL));
  pthread_mutex_init(&mtx, NULL);
  pthread_cond_init(&cond, NULL);
  pthread_t consumer, producer;
  pthread_create(&consumer, NULL, func1, NULL);
  pthread_create(&producer, NULL, func2, NULL);

  pthread_join(consumer, NULL);
  pthread_join(producer, NULL);
  pthread_cond_destroy(&cond);
  pthread_mutex_destroy(&mtx);
  return 0;
}

0 人点赞