《操作系统》课程实验二

该内存不能为read是什么意思  时间:2021-01-19  阅读:()

实验报告高级进程间通信问题班级:无47姓名:刘前1学号:2014011216日期:2016年11月25日操作平台:Windows8.
1编程语言:C++1清华大学电子工程系(E-mail:liuqian14@mails.
tsinghua.
edu.
cn)《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前2高级进程间通信问题实验目的:1.
通过对进程间高级通信问题的编程实现,加深理解进程间高级通信的原理;2.
对Windows或Linux涉及的几种高级进程间通信机制有更进一步的了解;3.
熟悉Windows或Linux中定义的与高级进程间通信有关的函数.
实验题目:本实验共有2个实验题目,任选其中之一.
不同实验的难度不同,基准分也不同,请同学根据自己的情况加以选择.
实验题目基准分二元自然数变量函数计算问题90快速排序问题100操作系统平台可选Windows或Linux,编程语言不限.
实验报告内容要求:1.
写出设计思路和程序结构,并对主要代码进行分析;2.
实际程序运行情况;3.
对提出的问题进行解答;4.
体会或者是遇到的问题.
注:本人在实验二中选择的是二元自然数变量函数计算问题.
《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前3二元自然数变量函数计算问题一、问题描述及实验要求1.
问题描述:设有二元自然数变量函数,其中请编程建立3个并发协作进程或线程,分别完成计算、和.
2.
实验步骤(a)首先创建三个线程(或进程),分别执行函数、和计算;(b)线程(或进程)之间的通信可以选择下述机制之一进行:管道(无名管道或命名管道)消息队列共享内存(c)通过适当的函数调用创建上述IPC对象,通过调用适当的函数调用实现数据的读出与写入;(d)需要考虑线程(或进程)间的同步;(e)线程(或进程)运行结束,通过适当的系统调用结束线程(或进程).
3.
实验平台和编程语言:自由选择Windows或Linux.
编程语言不限.
4.
思考题1.
你采用了你选择的机制而不是另外的两种机制解决该问题,请解释你做出这种选择的理由.
2.
你认为另外的两种机制是否同样可以解决该问题如果可以请给出你的思路;如果不能,请解释理由.
《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前4二、设计思路首先对二元自然数变量函数计算问题进行分析.
函数f(m)的功能是计算输入自然数m的阶乘;函数g(n)的功能是计算输入自然数n对应的斐波那契数;函数F将函数f和g的计算结果相加.
通过分析可以看出,如果不要求使用高级进程间通信,即使是编程初学者,也能在很短的时间内完成这一问题,但是本次实验要求使用高级进程间通信解决这一问题,因而需要IPC机制来实现进程(线程)之间的通信.
IPC机制要求对三个函数建立各自的线程,函数间参数或数值结果的传递采用消息队列、共享内存或管道等高级进程间通信进制来实现.
本人采用匿名管道的方式实现进程间通信.
根据问题要求,本问题需要两个匿名管道,一个管道实现函数f和F之间的通信,另一个管道实现g和F之间的通信,为方便下文表述将两个管道分别称为管道A、B.
每个管道在被创建时都会生成两个句柄,分别为管道的读句柄和写句柄,分别与WriteFile和ReadFile函数协同实现向管道的写入和读取.
使用匿名管道机制解决本问题的主要思路是:1.
主函数main()输入两个自然数,分别为函数f的参数m和g的参数n;2.
将m写入管道A,n写入管道B;3.
f函数从管道A中读取已经被写入的m,经过计算得到结果f(m),并将结果写回管道A;4.
g函数从管道B中读取已经被写入的n,经过计算得到结果g(n),并将结果写回管道B;5.
F函数从管道A和B中分别读取f(m)和g(n),相加得到最后结果;6.
将函数F的最后结果输出.
综合以上分析,可以看出,本实验的思路非常清晰,关键是如何使用Windows中管道机制的函数实现以上过程.
三、程序结构1.
基本数据结构及函数:本次程序比较简单,没有使用特殊的数据结构,主要涉及的变量包括管道的读写句柄、线程的句柄,以及管道机制和线程中常用的函数.
程序中具体使用的变量和函数及其说明如下:《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前5变量说明HANDLEHREAD_fFf和F之间的管道读句柄HANDLEHWRITE_fFf和F之间的管道写句柄HANDLEHREAD_gFg和F之间的管道读句柄HANDLEHWRITE_gFg和F之间的管道写句柄HANDLEf_threadf函数对应的线程HANDLEg_threadg函数对应的线程HANDLEF_threadF函数对应的线程自己编写的函数及说明如下:函数说明intf(intm)函数f(m)intg(intn)函数g(n)voidWINAPIf_PIPE_RW(PVOIDpvParam)f函数向管道的读写操作voidWINAPIg_PIPE_RW(PVOIDpvParam)g函数向管道的读写操作voidWINAPIF_PIPE_RW(PVOIDpvParam)F函数向管道的读写操作Windows.
h中对管道的操作函数:与管道相关的函数函数说明CreatePipe()创建管道ReadFile()读取数据WriteFile()写入数据CloseHandle()关闭管道Windows.
h中对线程的操作函数:与线程的相关函数函数说明CreateThread()创建线程CloseHandle()关闭线程WaitForSingleObject()等待进程结束2.
实现方法:首先,使用递归方法实现函数f和函数g.
函数f(m)的功能是求m的阶乘,而函数g(n)的功能是求第n个斐波那契数.
然后创建三个线程,f、g和F三个函数分别对应线程f_thread,g_thread和F_thread.
《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前6对于f的线程f_thread,调用的函数为f_PIPE_RW,该函数实现从管道A中读取参数m,进行运算后将结果写回管道A;对于g的线程g_thread,调用的函数为g_PIPE_RW,该函数实现从管道B中读取参数n,进行运算后将结果写回管道B;对于F的线程F_thread,调用的函数为F_PIPE_RW,该函数是本程序的核心函数,一开始向管道写入函数f和g各自的参数,最后从管道读取两个函数的返回值,相加得到最终结果,输出到控制台窗口.
因此,程序中核心的操作由函数F_PIPE_RW完成,通过在主函数建立调用线程F_thread即可实现.
当线程F_thread结束时,函数F(m,n)的结果已经输出.
3.
对程序结构的解释:上图清楚展示了本程序的结构图,但没有对线程进行解说明,现补充如下:程序中,main()创建线程F_thread,该线程调用了F_PIPE_RW函数.
F_PIPE_RW函数是程序的核心函数,问题解决的过程由该函数实现.
F_PIPE_RWf_PIPE_RW管道A管道B将函数f的参数m写入管道将函数g的参数n写入管道计算f(m)计算g(n)控制台窗口输入函数f、g的参数m和n输出F(m,n)的结果g_PIPE_RW将g(n)写入管道将f(m)写入管道《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前7首先,F_PIPE_RW从主函数main()中接收到输入的两个自然数,接着建立起两个管道A和B,分别实现f与F之间的通信和g与F之间的通信.
管道建立成功后,将m写管道A,将n写入管道B.
再建立两个线程f_thread和g_thread,分别实现f函数和g函数从管道读取数据、处理并将结果写回对应的管道.
使用两个WaitForSingleObject()函数分别等待两个线程的结束.
两线程结束表明已经将函数结果写回管道,此时再分别从管道中读取f(m)和g(n),两者相加输出F(m,n)=f(m)+g(n)结果即可.
四、代码分析1.
全局变量:程序中定义的全局变量有:DWORDnum_of_bytes=sizeof(int);HANDLEHREAD_fF;//f和F之间的管道读句柄HANDLEHWRITE_fF;//f和F之间的管道写句柄HANDLEHREAD_gF;//g和F之间的管道读句柄HANDLEHWRITE_gF;//g和F之间的管道写句柄其中DWORDnum_of_bytes作为管道的ReadFile和WriteFile函数的参数,表示写入或读取数据的字节数.
因为本程序中每次写入或读取的数均为一个int型变量,因而定义num_of_bytes=sizeof(int).
两个管道的读写句柄也用全局变量,是为了减少函数之间传递参数造成不必要的麻烦.
2.
函数f(m)和g(n)根据函数的表达式,使用递归的思想即可实现两个函数.
//f函数(功能是计算阶乘)intFunc_f(intm){if(m==1)return1;elsereturn(m*Func_f(m-1));}//g函数(斐波那契数列)intFunc_g(intn){if(n==1||n==2)return1;elsereturn(Func_g(n-1)+Func_g(n-2));}《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前83.
f_PIPE_RW函数f_PIPE_RW函数实现了从管道中读取参数m,经过运算再将结果写入管道.
对f来说,f向F传递数据相当于向管道写入数据;f从F得到数据相当于从管道读入数据.
voidWINAPIf_PIPE_RW(PVOIDpvParam)//实现f函数从管道读取和向管道写入数据{DWORDread_dword,write_dword;//返回实际读取或写入的字节数intpara_m;//管道内的数据,即为参数mwhile(!
ReadFile(HREAD_fF,¶_m,num_of_bytes,&read_dword,NULL));//从管道中读取参数m,使用while表示等待数据直到成功读入intf_result=Func_f(para_m);//对读取的参数m使用f函数,得到结果while(!
WriteFile(HWRITE_fF,&f_result,num_of_bytes,&write_dword,NULL));//将f函数的结果写入管道,使用while表示直到成功写入}4.
g_PIPE_RW函数g_PIPE_RW函数实现了从管道中读取参数m,经过运算再将结果写入管道.
对g来说,g向F传递数据相当于向管道写入数据;g从F得到数据相当于从管道读入数据.
voidWINAPIg_PIPE_RW(PVOIDpvParam)//实现g函数从管道读取和向管道写入数据{DWORDread_dword,write_dword;//返回实际读取或写入的字节数intpara_n;//管道内的数据,即为参数nwhile(!
ReadFile(HREAD_gF,¶_n,num_of_bytes,&read_dword,NULL));//从管道中读取参数n,使用while表示等待数据直到成功读入intg_result=Func_g(para_n);//对读取的参数n使用g函数,得到结果while(!
WriteFile(HWRITE_gF,&g_result,num_of_bytes,&write_dword,NULL));//将g函数的结果写入管道,使用while表示直到成功写入}5.
F_PIPE_PW函数F_PIPE_RW函数是程序的核心函数,实现了问题完整的求解过程.
《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前9a)创建两个管道:其中安全性参数的设置参照了课件上的代码.
//安全性参数设置SECURITY_ATTRIBUTESsafF,sagF;//对应于两个管道的安全性//安全性的参数设置,建立f和F之间的管道safF.
nLength=sizeof(SECURITY_ATTRIBUTES);safF.
lpSecurityDescriptor=NULL;safF.
bInheritHandle=TRUE;CreatePipe(&HREAD_fF,&HWRITE_fF,&safF,0);//安全性的参数设置,建立g和F之间的管道sagF.
nLength=sizeof(SECURITY_ATTRIBUTES);sagF.
lpSecurityDescriptor=NULL;sagF.
bInheritHandle=TRUE;CreatePipe(&HREAD_gF,&HWRITE_gF,&sagF,0);b)将输入的m和n写入对应的管道:核心是使用WriteFile()函数将sizeof(int)字节数的数据写入管道中.
//将输入的两个参数写入管道intm=para[0];intn=para[1];DWORDdword_fF,dword_gF;//返回实际读入的字节数while(!
WriteFile(HWRITE_fF,&m,num_of_bytes,&dword_fF,NULL));//F函数向管道写入f函数的参数mwhile(!
WriteFile(HWRITE_gF,&n,num_of_bytes,&dword_gF,NULL));//F函数向管道写入g函数的参数nc)两个线程分别计算f(m)和g(n):使用WaitForSingleObject()函数等待线程结束.
HANDLEf_thread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(f_PIPE_RW),NULL,0,NULL);//建立f函数读写的线程HANDLEg_thread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(g_PIPE_RW),NULL,0,NULL);//建立g函数读写的线程WaitForSingleObject(f_thread,INFINITE);//f_thread线程结束时,f(m)已写入管道WaitForSingleObject(g_thread,INFINITE);//g_thread线程结束时,g(n)已写入管道《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前10d)读取管道中返回的计算结果,输出最后结果:intf_result,g_result;//分别表示f函数和g函数的返回值while(!
ReadFile(HREAD_fF,&f_result,num_of_bytes,&dword_fF,NULL));//F函数从管道中读取f函数的返回值while(!
ReadFile(HREAD_gF,&g_result,num_of_bytes,&dword_gF,NULL));//F函数从管道中读取g函数的返回值intF_result=f_result+g_result;//F(m,n)=f(m)+g(n)cout<主函数建立F_PIPE_RW函数对应的线程:HANDLEF_thread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(F_PIPE_RW),¶,0,NULL);WaitForSingleObject(F_thread,INFINITE);//F函数的线程结束时,已经输出了函数返回值CloseHandle(F_thread);//关闭线程句柄以上代码通过管道实现了三个进程间的通信,最后的输出即为F(m,n)的计算结果.
五、程序运行结果:以下通过若干例子测试程序的正确性.
1.
m=2,n=3程序运行结果:********请输入两个自然数m和n********23输出结果*F(2,3)=4请按任意键继续.
.
.
《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前11验证:f(m)=f(2)=2!
=2;g(n)=g(3)=1+1=2;F(m,n)=F(2,3)=2+2=4.
验证结果正确.
2.
m=10,n=8程序运行结果:********请输入两个自然数m和n********108输出结果*F(10,8)=3628821请按任意键继续.
.
.
验证:f(m)=f(10)=10!
=3628800;g(n)=g(8)=21;F(m,n)=F(10,8)=3628800+21=3628821.
验证结果正确.
同样,测试的其他例子都证明程序是正确的.
3.
另外,程序还设置了简单的输入合法性判断,当m,n输入为00时,程序运行结果为:********请输入两个自然数m和n********00Error:输入有误!
请输入两个自然数!
请按任意键继续.
.
.
总之,程序的运行结果是正确的.
六、思考题1.
你采用了你选择的机制而不是另外的两种机制解决该问题,请解释你做出这种选择的理由.
答:本实验提供了三种可选的高级进程间通信机制,分别为消息队列、共享内存和管道.
之所以选择管道机制主要有以下原因:《操作系统》课程实验二:高级进程间通信问题二元自然数变量函数计算问题2014011216刘前12a)操作系统课程讲解了Linux系统下消息队列的实现方法,但是没有具体讲解Windows如何实现,因为我选择的是Windows操作系统,所以首先不选择消息队列机制;b)共享内存和管道的思路都比较清晰简单,但是共享内存对内存的映射、清理等感觉有些复杂,而管道的操作比较简单,很容易按照思路一步步实现;c)课件中只列出了共享内存常用的一些函数,但是没有给出具体的实现方法,因而还需要查阅一些课外资料;而对管道机制的具体实现则举了实例,理解了之后感觉实现起来比较简单,其中程序中关于安全性部分的参数就是参照了课件上的内容;管道机制分为两种,包括匿名管道和命名管道.
匿名管道比命名管道需要更少的开销,但是提供有限的服务,由于本题只需要来回一次数据的传递,因而对管道服务的要求不高,所以采用了容易实现、开销少的匿名管道.
2.
你认为另外的两种机制是否同样可以解决该问题如果可以请给出你的思路;如果不能,请解释理由.
答:除去管道之外,消息队列和共享内存机制同样可以解决进程(线程)间通信的问题.
a)消息队列机制:Windows操作系统下与Linux类似,也可以为当前执行的每个程序维护一个消息队列.
线程将消息放入程序的消息队列中.
消息队列可以看做用于存储消息的区域,不同的进程(线程)可以将消息放入消息队列或者从消息队列中取出消息.

HostKvm - 夏季云服务器七折优惠 香港和韩国机房月付5.95美元起

HostKvm,我们很多人都算是比较熟悉的国人服务商,旗下也有多个品牌,差异化多占位策略营销的,商家是一个创建于2013年的品牌,有提供中国香港、美国、日本、新加坡区域虚拟化服务器业务,所有业务均对中国大陆地区线路优化,已经如果做海外线路的话,竞争力不够。今天有看到HostKvm夏季优惠发布,主要针对香港国际和韩国VPS提供7折优惠,折后最低月付5.95美元,其他机房VPS依然是全场8折。第一、夏...

hosthatch:14个数据中心15美元/年

hosthatch在做美国独立日促销,可能你会说这操作是不是晚了一个月?对,为了准备资源等,他们拖延到现在才有空,这次是针对自己全球14个数据中心的VPS。提前示警:各个数据中心的网络没有一个是针对中国直连的,都会绕道而且ping值比较高,想买的考虑清楚再说!官方网站:https://hosthatch.com所有VPS都基于KVM虚拟,支持PayPal在内的多种付款方式!芝加哥(大硬盘)VPS5...

轻云互联(19元)香港高防云服务器 ,美国云服务器

轻云互联成立于2018年的国人商家,广州轻云互联网络科技有限公司旗下品牌,主要从事VPS、虚拟主机等云计算产品业务,适合建站、新手上车的值得选择,香港三网直连(电信CN2GIA联通移动CN2直连);美国圣何塞(回程三网CN2GIA)线路,所有产品均采用KVM虚拟技术架构,高效售后保障,稳定多年,高性能可用,网络优质,为您的业务保驾护航。活动规则:用户购买任意全区域云服务器月付以上享受免费更换IP服...

该内存不能为read是什么意思为你推荐
主机租用注册域名主机租用免费vps服务器免费VPS服务器。和免费的好用虚拟主机手机网站空间手机登陆qq空间网址是什么?1g虚拟主机我要做一个下载资料类网站,刚买了一个虚拟主机1G的,提供商说一次,只能上传一个小于10M的文件论坛虚拟主机最适合做论坛的虚拟主机是什么?厦门虚拟主机新手用什么虚拟主机好?中文域名什么是中文域名?备案域名域名一共有几种?哪些域名需要备案?域名交易域名怎么交易?域名是什么你好,请问域名是指什么啊?
idc评测 香港bgp机房 ddos BWH 免费ftp空间 e蜗 hostloc hinet 360云服务 空间购买 沈阳主机托管 免费ftp wordpress中文主题 万网主机 买空间网 国外代理服务器 什么是dns 服务器机柜 so域名 香港打折信息 更多