条件变量(实现同步)

条件变量

作用: 用于实现线程间同步
条件变量通过提供线程等待,直到被唤醒的进程唤醒,从而实现线程同步;条件变量本身不具备条件判断功能;也就是意味着什么时候该等待,什么时候该唤醒等待的线程,都需要用户来控制;
流程 需要和互斥锁搭配使用, 用户对临界资源进行判断, 如果需要那么就要将其加入到等待队列上, (判断条件需要循环判断, 因为先被唤醒的可能不是该线程, 那么就可能发生错误), 不同的角色应该等待在不同的等待队列上
原理 当需要等待的时候, 将该线程放入到等待队列上直到被唤醒。(提高性能)

实现过程

1. 定义条件变量

变量类型: pthread_cond_t ;

2.条件变量的初始化

int pthread_cond_init(pthread_cond_t *restrict cond,
const pthread_condattr_t *restrict attr);

cond: 所定义的条件变量
attr: 锁的属性, 不设置属性可置为 NULL

3. 条件不满足, 线程需要等待

int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex); 

cond 这个线程改在那个条件变量上等待
mutex 这个条件变量是针对那个互斥锁的(因为条件变量中等待队列)
作用: 将该线程加入到该条件变量的等待队列上, 直到被唤醒

4. 条件满足, 换线条件变量等待队列上的线程

  int pthread_cond_broadcast(pthread_cond_t *cond);  
  int pthread_cond_signal(pthread_cond_t *cond);

broadcast : 唤醒cond条件变量上的所有线程
signal : 唤醒cond条件变量等待队列上的至少一个线程

销毁条件变量

int pthread_cond_destroy(pthread_cond_t *cond)

销毁这个以及初始化的条件变量

使用示例

创建4个生产者线程负责生产, 一个队列仓库, 仓库满了后生产者就不能继续往里面添加数据, 创建4个消费者线程, 如果仓库的库存为0, 那么就不能在里面去数据
代码如下:

#include <iostream>
#include <queue>
#include <pthread.h>
#include <stdio.h>
#define MAX_CAPACITY 5

using namespace std;
class Queue{
  queue<int> _store;
  int _capacity;
  pthread_mutex_t mutexs;
  pthread_cond_t  cond_Preducer;
  pthread_cond_t  cond_Consumer;
  public:
  Queue(int capacity = MAX_CAPACITY)
    :_capacity(capacity)
  {
    pthread_mutex_init(&mutexs, NULL);
    pthread_cond_init(&cond_Consumer, NULL);
    pthread_cond_init(&cond_Preducer, NULL); 
  }
  ~Queue()
  {   
    pthread_mutex_destroy(&mutexs);
    pthread_cond_destroy(&cond_Consumer);
    pthread_cond_destroy(&cond_Preducer); 
  }

  bool push(const int& data)
  {
      pthread_mutex_lock(&mutexs);
      while(_capacity ==_store.size())
      {
        pthread_cond_signal(&cond_Consumer);
        pthread_cond_wait(&cond_Preducer,&mutexs);
      }
      _store.push(data);
      pthread_cond_signal(&cond_Consumer);
      pthread_mutex_unlock(&mutexs);
    return true;
  }

  bool pop(int& data)
  {
    pthread_mutex_lock(&mutexs);
    while(_store.empty())
    {
      pthread_cond_wait(&cond_Consumer,&mutexs);
    }
    data = _store.front();
    _store.pop();
    pthread_cond_signal(&cond_Preducer);
    pthread_mutex_unlock(&mutexs);
    return true;
  }
};

void* run_push(void* arg)
{
  int i=0;
 Queue* p =  (Queue*)arg;
  while(1)
  {
    p->push(i++);
    printf("压入一个元素val: %d\n",i);
  }
  return NULL;
}

void* run_pop(void* arg)
{
  Queue* p = (Queue*)arg;
  int data;
  while(1)
  {
    p->pop(data);
    printf("获取到一个值val: %d\n", data);
  }
  return NULL;
}


int main()
{
  pthread_t Consumer[4];
  pthread_t Preducer[4];
  Queue arr;
  
  for(int i=0;i<4;i++)
  {
    pthread_create(&Consumer[i], NULL, run_pop,(void*)&arr);
  }

  for(int i=0;i<4;i++)
  {
    pthread_create(&Preducer[i], NULL, run_push,(void*)&arr);
  }
  

  for(int i=0;i<4;i++)
  {
    pthread_join(Consumer[i],NULL);
  }
  for(int i=0;i<4;i++)
  {
    pthread_join(Preducer[i],NULL);
  }

  return 0;
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值