//reader_writer.c
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
/* 写者写完通知读者去读
读者读完通知写者去写 */
typedef struct{
int value;
int r_wait;
pthread_mutex_t r_mutex;
pthread_cond_t r_cond;
int w_wait;
pthread_mutex_t w_mutex;
pthread_cond_t w_cond;
}Storage;
void set_value(Storage *s, int value)
{
s->value = value;
}
int get_value(Storage *s)
{
return s->value;
}
void *set_fn(void *arg)
{
Storage *s = (Storage *)arg;
int i = 0;
for(; i < 100; i++){
set_value(s, i+100);
printf("writer write %d\n",i+100);
pthread_mutex_lock(&s->r_mutex);
//判断读者是否调用wait函数,如果调用了wait函数,那么写者就调用broadcast唤醒读者
while(s->r_wait == 0){
pthread_mutex_unlock(&s->r_mutex);
sleep(1);
pthread_mutex_lock(&s->r_mutex);
}
s->r_wait = 0;
pthread_mutex_unlock(&s->r_mutex);
pthread_cond_broadcast(&s->r_cond);
//设置写者调用了wait函数,等待读者通知
pthread_mutex_lock(&s->w_mutex);
s->w_wait = 1;
pthread_cond_wait(&s->w_cond, &s->w_mutex);
pthread_mutex_unlock(&s->w_mutex);
}
return (void *)0;
}
void *get_fn(void *arg)
{
Storage *s = (Storage *)arg;
int i = 0;
for(; i < 100; i++){
//设置读者调用了wait函数,等待写者通知(r_wait和读者的wait函数绑定,1表示调用了wait函数)
pthread_mutex_lock(&s->r_mutex);
s->r_wait = 1;
pthread_cond_wait(&s->r_cond, &s->r_mutex);
pthread_mutex_unlock(&s->r_mutex);
printf("reader read %d\n",get_value(s));
//读者通知写者再写
pthread_mutex_lock(&s->w_mutex);
while(s->w_wait == 0){
pthread_mutex_unlock(&s->w_mutex);
sleep(1);
pthread_mutex_lock(&s->w_mutex);
}
s->w_wait = 0;
pthread_mutex_unlock(&s->w_mutex);
pthread_cond_broadcast(&s->w_cond);
}
return (void *)0;
}
int main()
{
pthread_t reader,writer;
Storage s;
s.r_wait = 0;
pthread_mutex_init(&s.r_mutex, NULL);
pthread_cond_init(&s.r_cond, NULL);
s.w_wait = 0;
pthread_mutex_init(&s.w_mutex, NULL);
pthread_cond_init(&s.w_cond, NULL);
if(pthread_create(&reader, NULL, get_fn, (void *)&s) < 0){
printf("pthread_create failed\n");
}
if(pthread_create(&writer, NULL, set_fn, (void *)&s) < 0){
printf("pthread_create failed\n");
}
pthread_join(reader, NULL);
pthread_join(writer, NULL);
pthread_mutex_destroy(&s.r_mutex);
pthread_mutex_destroy(&s.w_mutex);
pthread_cond_destroy(&s.r_cond);
pthread_cond_destroy(&s.w_cond);
return 0;
}