linux c++(线程 & 生产者和消费者模型 & 条件变量)

生产者和消费者模型

条件变量用来阻塞线程等待某个事件的发生,并且当等待的事件发生时,阻塞线程会被通知。

互斥锁一个明显的缺点是它只有两种状态:锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用

  • 等待条件有两种方式:无条件等待pthread_cond_wait()和计时等待
    • pthread_cond_wait(&cond, &mutex);
    • int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
  • 销毁一个条件变量
    • int pthread_cond_destroy(pthread_cond_t *cond);
  • 初始化一个条件变量
    • int pthread_cond_init(pthread_cond_t *restric cond,const pthread_condattr_t *restrict attr);
    • pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  • 唤醒至少一个阻塞在条件变量cond上的线程
    • int pthread_cond_signal(pthread_cond_t *cond);
  • 唤醒阻塞在条件变量cond上的全部线程
    • int pthread_cond_broadcast(pthread_cond_t *cond);

避免不必要的竞争

  // #include <pthread.h>
  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  int beginnum = 1000;
  typedef struct _ProdInfo{
      int num;
      struct _ProdInfo *next;
  }ProdInfo;
  ProdInfo *Head =NULL;
 void * thr_producter(void *arg)
  {   
      //负责在链表添加数据
      while(1)
      {   
          ProdInfo *prod =(ProdInfo*)malloc(sizeof(ProdInfo));
          prod->num = beginnum++;
          printf("------%s----------%lu--------%d\n",__FUNCTION__,pthread_self(),prod->num);
          pthread_mutex_lock(&mutex);
          //add to list
          prod->next = Head;
          Head = prod;
          pthread_mutex_unlock(&mutex);
          //发起通知
          pthread_cond_signal(&cond);
          sleep(rand()%2);
      }
      pthread_exit(NULL);
  }
 void *thr_custmer(void *arg)
  {
      ProdInfo *prod = NULL;
      while(1)
      {   
          //取链表的数据
          pthread_mutex_lock(&mutex);
      //    if(Head == NULL)
          while(Head == NULL)
          {   
              pthread_cond_wait(&cond,&mutex); //再次之前必须先加锁
          }   
          prod = Head;
          Head = Head->next;
          printf("------%s----------%lu--------%d\n",__FUNCTION__,pthread_self(),prod->num);
          pthread_mutex_unlock(&mutex);
          sleep(rand()%4);
          free(prod);
      }   
      return NULL;
  }
  int main()
  {
      pthread_attr_t attr;
      pthread_attr_init(&attr);
      pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
      pthread_t tid[5];
      pthread_create(&tid[0],&attr,thr_producter,NULL);                                        
      pthread_create(&tid[1],&attr,thr_custmer,NULL);                                          
      pthread_create(&tid[2],&attr,thr_custmer,NULL);                                          
      pthread_create(&tid[3],&attr,thr_custmer,NULL);                                          
      pthread_create(&tid[4],&attr,thr_custmer,NULL);                                          
      pthread_attr_destroy(&attr);
      pthread_exit(NULL);
      pthread_mutex_destroy(&mutex);
      pthread_cond_destroy(&cond);
  }

posted on 2021-05-07 15:51  lodger47  阅读(154)  评论(0)    收藏  举报

导航