多线程中条件变量的使用:
// 线程同步之条件变量
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
using namespace std;
// 一个简单的缓冲区类
struct SimpleBuffer
{
static const int buffer_size = 8;
int buffer[8];
int pos;
SimpleBuffer()
{
memset(buffer,0,sizeof(int) * 64);
pos = -1;
}
bool Full()
{
if(pos == buffer_size - 1)
{
return true;
}
return false;
}
bool Empty()
{
if(pos == -1)
return true;
return false;
}
bool Push(int data)
{
if(pos == buffer_size - 1)
return false;
buffer[++pos] = data;
return true;
}
bool Pop(int& data)
{
if(pos == -1)
return false;
data = buffer[pos--];
return true;
}
};
// 公共缓冲区,给生产者和消费者读写
SimpleBuffer common_buffer;
// 条件变量
// 缓冲区未满条件变量
pthread_cond_t cond_buffer_not_full;
// 缓冲区不为空条件变量
pthread_cond_t cond_buffer_not_empty;
// 缓冲区锁
pthread_mutex_t buffer_lock;
// 生产者线程
void* producer(void* data)
{
int count = 0;
while(count < 64)
{
++count;
// 加锁
pthread_mutex_lock(&buffer_lock);
// 等待缓冲区不满
while (common_buffer.Full()) {
pthread_cond_wait(&cond_buffer_not_full,&buffer_lock);
}
// 往缓冲区中添加数据
common_buffer.Push(count);
// 通知消费者,缓冲区不为空
pthread_cond_signal(&cond_buffer_not_empty);
// 解锁
pthread_mutex_unlock(&buffer_lock);
sleep(1);
}
}
// 消费者线程
void* consumer(void* data)
{
int count = 0;
while(count < 64)
{
// 加锁
pthread_mutex_lock(&buffer_lock);
// 等待缓冲区不为空
while(common_buffer.Empty())
{
pthread_cond_wait(&cond_buffer_not_empty,&buffer_lock);
}
// 从缓冲区中消耗数据
int data;
common_buffer.Pop(data);
cout << data << endl;
// 通知生产者,缓冲区不满
pthread_cond_signal(&cond_buffer_not_full);
// 解锁
pthread_mutex_unlock(&buffer_lock);
++count;
}
}
// 主函数
int main(int argc,char* argv[])
{
// 初始化缓冲区锁
pthread_mutex_init(&buffer_lock,0);
// 初始化两个条件变量
pthread_cond_init(&cond_buffer_not_empty,0);
pthread_cond_init(&cond_buffer_not_full,0);
// 定义两个线程id
pthread_t thd1,thd2;
// 创建生产者和消费者线程
pthread_create(&thd1,0,consumer,0);
pthread_create(&thd2,0,producer,0);
// 等待两个线程运行结束
pthread_join(thd1,0);
pthread_join(thd2,0);
// 销毁锁和条件变量
pthread_cond_destroy(&cond_buffer_not_full);
pthread_cond_destroy(&cond_buffer_not_empty);
pthread_mutex_destroy(&buffer_lock);
return 0;
}