/***************************************************************************************************************
*
*定义读者写者函数,写者准备对文件写操作,如果文件被没有被写或读,则写者函数阻塞在这里进行写文件,其他读者或写者不可对文件操作,然后
*写者函数返回,接下来读者函数进行读文件的读操作,读者读文件时,读者函数阻塞在这里,不允许写者对文件操作,但是允许下一个读者再进来读
*文件,然后读毕返回释放读函数,然后系统接着对两个读者写者线程调用,继续对文件进行读取循环。
*
*运行命令为:
*#gcc read.c -o read -lpthread
*#./read
*
****************************************************************************************************************/
#include
#include
#include
#include
sem_t w_sem, r_sem; //定义信号量共享指针
int read_count = 0;
void *reader(void *arg)
{
//int read_count = 0; //会造成死锁
while (1)
{
sem_wait(&r_sem); //允许一个读者读书,用来阻塞当前线程直到信号量r_sem的值大于0,解除阻塞后将r_sem的值减一,表明公共资源经使用后减少
if (read_count == 0) //判断是否有读者读书
{
sem_wait(&w_sem); //有读者进入,不允许写文件,用来阻塞当前线程直到信号量w_sem的值大于0,解除阻塞后将w_sem的值减一,表明公共资源经使用后减少
}
read_count++; //读者人数+1
printf("the number of reader is:%d\n", read_count); //打印输出第read_count读者数量
sem_post(&r_sem); //允许读者读文件,增加信号量r_sem的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞
printf("the reader is reading!\n"); //打印输出读者在读书
sleep(1);
sem_wait(&r_sem); //允许一个读者读书,用来阻塞当前线程直到信号量r_sem的值大于0,解除阻塞后将r_sem的值减一,表明公共资源经使用后减少
read_count--; //读者数量-1
if (read_count == 0)
{
sem_post(&w_sem); //有读者进入,不允许写文件,用来阻塞当前线程直到信号量w_sem的值大于0,解除阻塞后将w_sem的值减一,表明公共资源经使用后减少
}
sem_post(&r_sem); //允许一个读者读书,用来阻塞当前线程直到信号量r_sem的值大于0,解除阻塞后将r_sem的值减一,表明公共资源经使用后减少
}
return (void *) 0; //返回任意类型的指针
}
void *writer(void *arg)
{
while (1)
{
sem_wait(&w_sem); //不允许多个写者同时写文件,一个原子操作,它的作用是从信号量w_sem的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法,阻塞当前线程直到信号量w_sem的值大于0,解除阻塞后将w_sem的值减一,表明公共资源经使用后减少
printf("the writer is writing!\n"); //输出写者正在写
sleep(1); //睡一会
sem_post(&w_sem); //允许写者写文件,增加信号量w_sem的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞
sleep(3); //睡一会
}
return (void *) 0;
}
int main()
{
pthread_t pid_reader, pid_reader2, pid_writer; //创建读者写者线程函数线程号
sem_init(&w_sem, 0, 1); //初始化一个定位在 w_sem 的匿名信号量,初始值为1,0表示此信号量进程内线程共享
sem_init(&r_sem, 0, 1); //初始化一个定位在 r_sem 的匿名信号量,初始值为1,0表示此信号量进程内线程共享
pthread_create(&pid_writer, NULL, writer, NULL); //创建并跳转到线程函数创建并跳转到参数为指向线程标识符的指针为 pid_writer 线程函数writer
pthread_create(&pid_reader, NULL, reader, NULL); //创建并跳转到线程函数创建并跳转到参数为指向线程标识符的指针为 pid_reader 线程函数reader
pthread_create(&pid_reader2, NULL, reader, NULL);//创建并跳转到线程函数创建并跳转到参数为指向线程标识符的指针为 pid_reader2 线程函数reader
pthread_join(pid_reader, NULL); //等待线程号为pid_reader线程函数结束
pthread_join(pid_reader2, NULL);//等待线程号为pid_reader2线程函数结束
pthread_join(pid_writer, NULL); //等待线程号为pid_writer线程函数结束
sem_destroy(&w_sem); //释放信号量w_sem
sem_destroy(&r_sem); //释放信号量r_sem
return 0;
}
阅读(4788) | 评论(0) | 转发(1) |