#include <cstddef>
#include <cstdio>
#include<iostream>
#include<pthread.h>
#include <unistd.h>
using namespace std;
struct Storage
{
//两个条件变量、两个互斥锁
int value;
pthread_cond_t rc;
pthread_mutex_t rm;
int r_wait;
pthread_cond_t wc;
pthread_mutex_t wm;
int w_wait;
};
void set_data(Storage *s,int value)
{
s->value=value;
}
int get_data(Storage *s)
{
return s->value;
}
//写者线程执行的线程运行函数
void* set_th(void* arg)
{
Storage*s=(Storage*)arg;
int i=1;
for(;i<=100;++i)
{
//往Storage中写入数据
set_data(s,i+100);
cout<<pthread_self()<<" write data : "<<i+100<<endl;
//写者写好了,下面判断读者准备好没
pthread_mutex_lock(&s->rm);
while(!s->r_wait) //判断读者线程是否准备好
{
pthread_mutex_unlock(&s->rm);
sleep(1);
pthread_mutex_lock(&s->rm);
}
s->r_wait=0;
pthread_mutex_unlock(&s->rm);
pthread_cond_broadcast(&s->rc); //读者线程已经准备好了,通知(唤醒)读者线程
//写者线程等待阻塞
//等待读者线程读取完数据后通知唤醒它
//然后继续写入数据
pthread_mutex_lock(&s->wm);
s->w_wait=1;
//写者线程阻塞,加入阻塞队列wc(条件变量内部是一个的等待队列,存放阻塞的线程)
pthread_cond_wait(&s->wc,&s->wm);
pthread_mutex_unlock(&s->wm);
}
return (void*)0;
}
//读者线程执行的线程运行函数
void* get_th(void* arg)
{
Storage* s=(Storage*)arg;
int i=1;
for(;i<=100;++i)
{
pthread_mutex_lock(&s->rm);
s->r_wait=1; //表示读者线程准备好了
pthread_cond_wait(&s->rc,&s->rm); //读者线程准备好了,将读者线程阻塞
pthread_mutex_unlock(&s->rm);
//读者线程被唤醒后从Storage中获取数据
int value= get_data(s);
cout<<pthread_self()<<"read data : "<<value<<endl;
pthread_mutex_lock(&s->wm);
//判断写者线程是否准备好
while(!s->w_wait)
{
pthread_mutex_unlock(&s->wm);
sleep(1);
pthread_mutex_lock(&s->wm);
}
s->w_wait=0;
pthread_mutex_unlock(&s->wm);
//去通知写者线程继续写入数据
pthread_cond_broadcast(&s->wc);
}
return (void*)0;
}
int main()
{
int err;
pthread_t rth,wth;
Storage s;
s.r_wait=0;
s.w_wait=0;
//初始化条件变量和信号量
pthread_cond_init(&s.rc,NULL);
pthread_cond_init(&s.wc,NULL);
pthread_mutex_init(&s.rm,NULL);
pthread_mutex_init(&s.wm,NULL);
//创建一个读者线程和一各读者线程
err=pthread_create(&rth,NULL,get_th,(void*)&s);
if(err!=0)
{
perror("create error");
}
err=pthread_create(&wth,NULL,set_th,(void*)&s);
if(err!=0)
{
perror("create error");
}
pthread_join(rth,NULL);
pthread_join(wth,NULL);
//销毁互斥量和条件变量
pthread_cond_destroy(&s.rc);
pthread_cond_destroy(&s.wc);
pthread_mutex_destroy(&s.rm);
pthread_mutex_destroy(&s.wm);
return 0;
}