Linux练习_线程练习_读者写者问题

经典线程同步案例 读者写者问题

案例介绍

在这里插入图片描述

  1. 进程:
  • 写者进程——负责写入数据
  • 读者进程——读取数据
  1. 分析:
  • 当写者进程还没写完数据之前,读者只能等待阻塞,当写者写完以后,通知读者可以进行读取数据。
  • 当读者读完数据后,反过来去通知写者继续写入数据
  1. 框图在这里插入图片描述

  2. 代码:

/*
 * 读者写者问题
 * 轮流写入读取100次,写一个读一个
 * 
 * */

#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

//共享资源
typedef struct
{
	int 								value;
	//读者条件变量和互斥锁
	pthread_cond_t 		rc;
	pthread_mutex_t 	rm;
	int 								r_wait;  //判断读者线程条件
	//写者条件变量和互斥锁
	pthread_cond_t 		wc;
	pthread_mutex_t 	wm;
	int 								w_wait;  //判断写者线程条件
	
}Storage,*pStorage;

/*写入函数*/
void set_data(pStorage s, int value)
{
	s->value = value;
}
/*读取函数*/
int get_data(pStorage s)
{
	return s->value;
}

/*写者线程执行的线程运行函数*/
void* set_th(void* arg)
{
	pStorage s = (pStorage)arg;
	int i=1;
	//循环100次
	for(;i<=10;i++){
		//写入数据并打印信息
		set_data(s, i+100);
		printf("0x%lx(%-5d) write data: %d\n", pthread_self(), i, i+100);
		
		pthread_mutex_lock(&s->rm);
		//判断读者线程是否准备好
		while(!s->r_wait){
		//循环,先解锁,让读者线程执行读取数据,再加锁判断条件是否满足
			pthread_mutex_unlock(&s->rm);
			sleep(1); //睡眠时,跳至读者线程s->r_wait = 1;前
			pthread_mutex_lock(&s->rm);
		}
		//读者条件清0
		s->r_wait = 0;
		pthread_mutex_unlock(&s->rm);
		//唤醒读取线程
		pthread_cond_broadcast(&s->rc); //跳至读者线程pthread_cond_wait(&s->rc, &s->rm); 下面
		
		/*写者线程等待阻塞
		*等待读者读取完数据后通知唤醒它
		*然后继续写入数据
		*/
		pthread_mutex_lock(&s->wm);
		s->w_wait = 1;
		pthread_cond_wait(&s->wc, &s->wm); //跳至判断s->w_wait循环体
		pthread_mutex_unlock(&s->wm);
	}
	
	return (void*)0;
}

/*读者线程执行的线程运行函数*/
void* get_th(void* arg)
{
	pStorage s = (pStorage)arg;
	int i=1;
	//循环100次
	for(;i<=10;i++){
		pthread_mutex_lock(&s->rm);
		//读者条件置1, 让写者执行写入数据
		s->r_wait = 1;
		//进入等待队列,等待唤醒
		pthread_cond_wait(&s->rc, &s->rm); //跳至写者线程判断s->r_wait循环体
		//解锁wait中的lock
		pthread_mutex_unlock(&s->rm); 
		
		//读取数据并输出
		int value = get_data(s); //资源被锁住时函数可以读取到数据吗?
		printf("0x%lx(%-5d) read data: %d\n", pthread_self(), i, value);
		
		pthread_mutex_lock(&s->wm);
		//判断写者线程是否准备好
		while(!s->w_wait){
			pthread_mutex_unlock(&s->wm);
			sleep(1); //跳至写者线程s->w_wait = 1;处
			pthread_mutex_lock(&s->wm);
		}
		s->w_wait = 0;
		pthread_mutex_unlock(&s->wm);
		pthread_cond_broadcast(&s->wc); //跳至写者线程pthread_cond_wait(&s->wc, &s->wm);下面
		
	}
	
	return (void*)0;
}

/*主函数*/
int main(void)
{
	int err;
	pthread_t  rth, wth;
	Storage s;
	s.r_wait = 0;
	s.w_wait = 0;
	
	pthread_mutex_init(&s.rm, NULL);
	pthread_mutex_init(&s.wm, NULL);
	pthread_cond_init(&s.rc, NULL);
	pthread_cond_init(&s.wc, NULL);
	
	//创建一个读者线程和写者线程
	err = pthread_create(&rth, NULL,get_th, (void*)&s);
	if(err)perror("pthread create error");
	
	err = pthread_create(&wth, NULL,set_th, (void*)&s);
	if(err)perror("pthread create error");
	
	pthread_join(rth,NULL);
	pthread_join(wth,NULL);
	
	pthread_mutex_destroy(&s.rm);
	pthread_mutex_destroy(&s.wm);
	pthread_cond_destroy(&s.rc);
	pthread_cond_destroy(&s.wc);
	
	return 0;
}

  1. 输出
0xb6559460(1    ) write data: 101
0xb6d5a460(1    ) read data: 101
0xb6559460(2    ) write data: 102
0xb6d5a460(2    ) read data: 102
0xb6559460(3    ) write data: 103
0xb6d5a460(3    ) read data: 103
0xb6559460(4    ) write data: 104
0xb6d5a460(4    ) read data: 104
0xb6559460(5    ) write data: 105
0xb6d5a460(5    ) read data: 105
0xb6559460(6    ) write data: 106
0xb6d5a460(6    ) read data: 106
0xb6559460(7    ) write data: 107
0xb6d5a460(7    ) read data: 107
0xb6559460(8    ) write data: 108
0xb6d5a460(8    ) read data: 108
0xb6559460(9    ) write data: 109
0xb6d5a460(9    ) read data: 109
0xb6559460(10   ) write data: 110
0xb6d5a460(10   ) read data: 110


Linux线程读者阅览问题课程设计是一个旨在帮助学生深入理解多线程编程和解决实际问题的课程。该课程设计可以分为以下几个主要内容。 首先,介绍多线程编程的概念和原理。该部分包括线程的创建、销毁和同步等基础知识。学生将学习如何利用线程来实现并发编程,并了解不同线程之间共享数据的方法。 其次,引入Linux操作系统中关于多线程读者阅览问题的背景和概念。多线程读者阅览问题是一个经典的多线程并发控制问题,学生将学习如何使用线程来解决该问题,以提高系统的效率和资源利用率。 然后,介绍用于解决多线程读者阅览问题的算法和数据结构。学生将学习不同的解决方案,如读者优先和写者优先等,并了解这些方案的优缺点和适用场景。此外,还将介绍相关的数据结构,如互斥锁、条件变量等。 接下来,学生将进行实际的编程练习和实验。他们将通过编写多线程读者阅览问题的程序来巩固所学知识,并通过实验来验证所实现的算法和数据结构的正确性和性能。在实验过程中,学生将面对各种问题和挑战,并学会调试和优化多线程程序。 最后,课程设计还将引导学生进行论文写作和报告演讲。学生将选择一个与多线程读者阅览问题相关的研究方向或应用领域,进行深入的文献调研和实验研究,并撰写一篇关于该方向的论文。同时,他们还要准备报告演讲,向同学们和教师们分享自己的研究成果。 综上所述,Linux线程读者阅览问题课程设计旨在通过理论学习、编程实践和实验研究,培养学生对多线程编程的深入理解和实际应用能力,为他们未来的工作和研究打下坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值