ImageVerifierCode 换一换
格式:DOC , 页数:28 ,大小:474.96KB ,
资源ID:854981      下载积分:20 积分
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 微信支付   
验证码:   换一换

加入VIP,免费下载资源
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【http://www.wodocx.com/d-854981.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(管道通信(操作系统课程设计).doc)为本站会员(精***)主动上传,沃文网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知沃文网(发送邮件至2622162128@qq.com或直接QQ联系客服),我们立即给予删除!

管道通信(操作系统课程设计).doc

1、操作系统课程设计说明书一、前言课程设计是检测学生课程效果的重要手段,是训练学生通过所学的知识解决实际问题的重要方式,同时也是实践性教学中的一个重要环节,它以某以课程为基础,可以涉及和课程相关的各个方面,是一门独立于课程之外的特殊课程。课程设计是让学生对所学的课程更全面的学习和应用,理解和掌握课程的相关知识。操作系统是一门重要的专业课,是计算机理论和应用的核心。操作系统课程设计,是一次对多学知识的综合演练,要求学生在操作系统的设计理念、整体机构、模块划分、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本内容的理解,同时,在课程设计方法以及上机操作等基本技能和科学作风方面收到比较系统

2、和严格的训练。在这次的课程设计中我们选择的题目是进程间通信消息机制的设计,实现消息的创建、发送和接收及在server端创建一个服务函数,从而形成C/S通讯模式。消息机制是消息通过消息队列的方式进行进程间消息的传递,通过此次课程设计,全面理解消息机制进程间通信方法。实现把死板的课本知识变得生动有趣,激发了学生的积极性。把学过的计算机操作系统的知识强化,能够把课堂上的知识通过自己设计的程序表示出来。二、目录一、前言1二、目录2三、设计目的与要求31、目的32、要求3四、运行环境41硬件环境:42软件环境:4五、总体设计51、fork()52、lockf()53、read()54、write()65

3、、signal(sig,function)6 6、open()67、getpid()78、Sleep()79、Exit()710、Wait()811.Unlink()8六、详细设计111、匿名管道112、服务器程序133、客户端程序15七、调试与测试17八、设计中遇到的问题及解决方法21九、源程序代码221、管道通信222、客户端程序25十、参考文献27十一、心得体会28三、设计目的与要求1、目的学习计算机软件技术,特别是计算机操作系统技术,除了需要刻苦努力外,还需要掌握软件和操作系统的原理与设计技巧。如何学习和掌握操作系统技术的原理与实际技巧呢?除了听课和读书之外,最好的方法就是在实践中练习

4、。例如,自己设计一个小型系统,多使用操作系统,多阅读和分析操作源代码等。但由于我们的条件和学时有限,在理论学习过程中没有给同学们提供更多的实验机会。本操作系统课程设计,是给同学提供一个集中实验的机会。希望同学们通过该设计加深对所学习课程的理解。2、要求利用UNIX系统提供的管道机制实现进程间的通信。(1)管道通信。利用pipe()和lockf()系统调用,编写程序,实现同族进程间的通信。使用系统调用pipe()建立一条管道线;创建子进程P1、P2、。子进程Pi分别向管道各写信息,而父进程则从管道中读出来自于各子进程的信息,实现进程家族间无名管道通讯。扩展之,使之成为客户/服务器模式,并完成一定

5、的任务(自己定义)。(2)命名管道通信:利用mkfifo(name,mode)或mknod(name,mode,0)创建一个命名管道,然后利用它和文件部分系统调用实现不同进程间的通信。改造之,使之成为客户/服务器模式,并完成一定的任务(自己定义)。四、运行环境1硬件环境:Cpu频率要满足使用需求内存大于2G2软件环境:Windows xp/7/8操作系统装有VMware虚拟机并可正常运行的PCVMware中安装有Linux/Unix系列的操作系统,如fedora,Red Hat等。五、总体设计1、fork()创建一个新进程。用法:int fork()其中返回int取值意义如下:0:创建子进程,

6、从子进程返回的id值0:从父进程返回的子进程id值-1:创建失败2、lockf()用作锁定文件的某些段或者整个文件。头文件:#include参数定义:int lockf(files,function,size);int files,function;long size;其中:files是文件描述符;function是锁定和解锁;1表示锁定;0表示解锁;Size是锁定或解锁的字节数,若用0,表示从文件的当前位置到文件尾。3、read()功能:从描述符为filedes的文件读信息。用法:#include ssize_tread(int filedes, void *buff, size_t nby

7、tes) ;返回:读到的字节数,若已到文件尾为0,若出错为-1。 在UNIX/Linux 可重定义为: intread(int fd, char *buff, unsigned nbytes) ;4、write()功能:向已打开的文件写数据。用法:#include ssize_t write(int filedes, const void * buff, size_t nbytes) ;返回值:若成功为已写入的字节数;出错为-1。intwrite(int fd, char *buff, unsigned nbytes) ;文件位置指针文件位置指针:每个打开文件都有一个与其相关联的“当前位移量”

8、。是从文件开始处计算的字节数。通常,读、写操作都从当前文件位置处开始,并使位移量增加所读或写的字节数。按系统默认,当打开一个文件时,除非指定O_APPEND选择项,否则该位移量被设置为0,即指向文件的开始处。文件位置指针可以通过系统调用lseek来移动。5、signal(sig,function)允许调用进程控制软中断信号的处理。头文件:#include参数定义signal(sig,function)intsig;void(*function)();返回值:成功时返回旧的(以前)函数描述,失败时返回SIG_ERR。说明:信号sig的值在头文件singal.h中有完整定义和描述,可用man 7

9、signal来获得帮助。其中:sig的值是:SIGHUP挂起SIGINT键盘按delete键或break键6、open() open可以打开或创建一个文件,并返回一个文件描述符。 调用方法:#include #include #include int open(const char * pathname, int oflag) ;int open(const char * pathname, int oflag, mode_t mode ) ;返回值:成功时为文件描述符,出错则为-1。open的参数pathname是要打开或创建的文件的名字。oflag参数可用来说明此函数的多个选择项。用下列一

10、个或多个常数进行或运算构成oflag参数(在fcntl.h中): O_RDONLY:只读打开。 O_WRONLY:只写打开。 O_RDWR :读写打开 O_APPEND 追加方式。 O_CREAT 若不存在则创建它。需同时使用第三个参数mode。 O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则出错。这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作。 O_TRUNC 如果此文件存在,则将其长度截短为0。 O_NOCTTY 如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端。 O_NONBLOCK 如果pathname指的是特殊文件,此选择项为

11、此文件的本次打开操作和后续的I / O操作设置非阻塞方式。7、getpid() 功能:取得当前进程pid. 返回值:当前进程pid.8、Sleep() 功能: 执行进程挂起一段时间。9、Exit() 功能:回收进程说占用的资源,实现进程的自我终止。10、Wait() 功能:用于将调用进程挂起,直至其子进程因暂停或终止而发来的软中断信号为止。11.Unlink() 功能:删除一个文件的目录项并减少它的链接数,若成功则返回0,否则返回-1,错误原因存于errno。如果想通过调用这个函数来成功删除文件,你就必须拥有这个文件的所属目录的写和执行权限。任务一:编制一段程序,实现进程的管道通信。使用系统调

12、用pipe()建立一条管道线。两个子进程p1和p2分别向管道各写一句话:child 1 is sending message!child 2 is sending message!而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。任务二:命名管道的通信例子中包括client端和server端。它们源代码文件名称分别为clt.c和svr.c,还有一个公共常量的有关文件被打包在文件fifo_hd.h编译方法是:cc o svr srv.ccc o clt clt.c先启动server端程序,方法为:./svr再换一个终端运行client端,方法是:./clt运行时,client只运行一次

13、就将退出,而server端作为服务器仍将继续运行,你再次启动client来请求服务。任务二、FIFO的用法1、创建用mkfifo或mknod创建一个命名管道。以mkfifo为例:#include#includeint mkfifo(const char *fifo_name, mode_t mode);/成功返回0,否则为-12、使用管道一经创建,就可向普通文件一样使用。可通过系统调用open,close,read,write,unlink等进行操作。管道打开过程中,变量O_NONBLOCK将影响打开后对文件的操作。默认情况下该变量不设置,也就是以阻塞方式打开。这样可以保证原子性操作。(因此可

14、以不考虑该参数。)在操作过程中,如果对一个管道进行写操作write,若对方没有以读方式打开将产生SIGPIPE。你可以捕获此信号进行处理。默认情况下是出现写错误。当最后一个写入者关闭了管道,将产生一个文件结束标志EOF。3、client、server可以以client/server方式使用FIFO。如果一个服务器有多个客户时,每个客户可通过一个well_known FIFO服务器连接。连接后可以通过well_known FIFO向服务器发送请求,所发信息的长度必须PIPE_BUF (4096)。如果客户服务器模式是并发型的话,则客户机不能再通过well_known FIFO回读信息。此时可采用

15、在已连接的客户与服务器之间建立一个私有通讯管道的办法来进行通信。该私有管道被服务器创建后可以以I/O方式打开,用于客户机和服务器之间进行通讯,以完成指定性工作。并发型客户机与服务器之间的通讯模式如图所示。匿名管道: 用户进程fd0 fd1 读 写 管道 命名管道:六、详细设计任务一:编制一段程序,实现进程的管道通信。使用系统调用pipe()建立一条管道线。两个子进程p1和p2分别向管道各写一句话:child 1 is sending message!child 2 is sending message!而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上程序编制一段程序,实现进程的管道通

16、信。使用系统调用pipe()建立一条管道线。两个子进程p1和p2分别向管道各写一句话:child 1 is sending message!child 2 is sending message!而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。1、匿名管道#include#include#includeint pid1,pid2;main()int fd2;char OutPipe100,InPipe100;pipe(fd);while(pid1=fork()=-1);if(pid1=0)lockf(fd1,1,0);sprintf(OutPipe,child 1 process i

17、s sending message!n);write(fd1, OutPipe,50);sleep(5);lockf(fd1,0,0);exit(0); else while(pid2=fork()=-1);if(pid2=0)lockf(fd1,1,0);sprintf(OutPipe,child 2 process is sending message!n);write(fd1,OutPipe,50);sleep(5);lockf(fd1,0,0);exit(0); else wait(0);read(fd0,InPipe,50);printf(%sn,InPipe);wait(0);re

18、ad(fd0,InPipe,50);printf(%sn,InPipe);exit(0);child 1is sending messagechild 2is sending message任务二:命名管道的通信例子中包括client端和server端。它们源代码文件名称分别为clt.c和svr.c,还有一个公共常量的有关文件被打包在文件fifo_hd.h编译方法是:cc o svr srv.ccc o clt clt.c先启动server端程序,方法为:./svr再换一个终端运行client端,方法是:./clt运行时,client只运行一次就将退出,而server端作为服务器仍将继续运行,

19、你再次启动client来请求服务。1、服务器程序#define my_fifo my_fifo#define file_name server.#include#include#include#includevoidterminate();intwell_known_id,tmp_id;chartmp_fil100;main(int argc,char *argv)intfd1,fd2;pid_tpid;charmy_buf100,my_fil100,my_tmp100;sprintf(my_buf,rm -f %s /dev/null,my_fifo);system(my_buf);/do

20、shell cmd rm -f my_fifo /dev/nullwell_known_id=tmp_id=-1;signal(SIGINT,terminate);if(mkfifo(my_fifo,S_IRWXU|S_IRWXG|S_IRWXO)=-1)fprintf(stderr,Create Well_known FIOF Error!n);exit(-1);fprintf(stderr,mkfifo OK!n);fprintf(stderr,A New Seession! Im waiting connection.n);loop1:if(fd1=open(my_fifo,0)=-1)

21、fprintf(stderr,Open well_known FIFO for readind Error!n);unlink(my_fifo);exit(-2); well_known_id=fd1;tmp_id=-1;fprintf(stderr,open my_fifo OK!n);if(read(fd1,my_buf,20)!=0)fprintf(stderr,My_buff=%sn,my_buf);strcpy(my_fil,file_name);strncat(my_fil,my_buf,5);strcpy(tmp_fil,my_fil);if(pid=fork()!=0)clos

22、e(fd1);wait();goto loop1;fprintf(stderr,Tmp_FIFO is: %s|n,my_fil);if(mkfifo(my_fil,S_IRWXU|S_IRWXG|S_IRWXO)=-1)fprintf(stderr,Create my_fil:%s FIFO Error!n,my_fil);exit(-1); /system(ls server*);if(fd2=open(my_fil,2)=-1)fprintf(stderr,Open %s Error!:%dn,my_fil,fd2);close(fd1); unlink(my_fifo);exit(-3

23、);tmp_id=fd2;if(write(fd2,my_buf,5)!=5)fprintf(stderr,Write %s Error!n,my_fil);close(fd2); close(fd1);unlink(my_fil); unlink(my_fifo);exit(-4);sleep(5);if(read(fd2,my_tmp,5)!=5)fprintf(stderr,read %s Error!n,my_fil);close(fd2); close(fd1);unlink(my_fil); unlink(my_fifo);exit(-5);else if(strncmp(my_t

24、mp,00000,5)!=0)close(fd2);close(fd1);fprintf(stderr,Filed to finish talking with %s!n,my_fil);unlink(my_fil);exit(-1);/goto loop1;elseclose(fd2);close(fd1);fprintf(stderr,OK to talking with %s!n,my_fil);unlink(my_fil);/unlink(my_fifo);exit(0);void terminate()if(well_known_id!=-1)close(well_known_id)

25、; unlink(my_fifo);if(tmp_id!=-1)close(tmp_id);unlink(tmp_fil);fprintf(stderr,The Server Program stoped by Signal:SIGINT!n);exit(0);2、客户端程序#define my_fifo my_fifo#define file_name server.#include#include#includemain(int argc,char *argv)intfd1,fd2,pid,pid1;charmy_buf100;charmy_fil100;charmy1buf100;if(

26、fd1=open(my_fifo,1)=-1)fprintf(stderr,Open well_known FIFO for readind Error!n);exit(-1); fprintf(stderr,Open %s OK!n,my_fifo);pid=getpid();sprintf(my_buf,%5.5d%6.6d%7.7d,pid,pid*10,pid*20);if(write(fd1,my_buf,20)!=0)strcpy(my_fil,file_name);strncat(my_fil,my_buf,5);fprintf(stderr,Send_fil: %sn,my_f

27、il);sleep(2);if(fd2=open(my_fil,2)=-1)fprintf(stderr,open %s Error!n,my_fil);close(fd1);exit(-2);fprintf(stderr,open %s OK!n,my_fil);if(read(fd2,my1buf,5)!=0)my1buf5=0;fprintf(stderr,Read from my_buf:%s!ntmy1buf:%s,my_buf,my1buf);if(strncmp(my_buf,my1buf,5)!=0)fprintf(stderr,Different occurs!n);strc

28、py(my_buf,0000000000);write(fd2,my_buf,5);/sleep(5);close(fd2);close(fd1);七、调试与测试任务一编译 gcc o pipe pipe.c执行 ./pipe结果任务二服务端 编译 gcc o server server.c 执行 ./server结果 服务器端客户端 编译 gcc o client client.c 执行./client 结果 客户端客户端和服务器建立连接后的服务器:信息传递成功客户端出错时:服务器也出错通过信号量sigint 中断服务器:八、设计中遇到的问题及解决方法 刚开始做的时候,对于任务二命名管道的实

29、现,感觉一头雾水,既不知道目的,还有怎样才算实现成功,更不用说程序实现细节了。但随着一步步的学习和理解,对管道的定义,性质及功能实现的了解,再加上调试,结合着运行结果,逐渐的了解了一个大致的轮廓。由于任务一在实验四已做过实验,下面主要就任务二中遇到的问题及解决办法加以阐述。 在看到程序代码的第一感觉就是有太多的函数没有掌握理解,比如关于文件操作的Read(),write(),wait(),还有fprintf(),以及一些系统调用函数,如fork(),pipe(),exit(),wait(),sleep(),unlink()等,但是通过阅读课本上的介绍加上课程设计指导书上的提示,偶尔还有百度百科

30、,终于对这些函数有了一定的理解。还有一个比较大的问题就是对程序实现的整体流程把握及基于管道通信的机制和原理的理解没有达到一定的深度,所以就算是后来把程序中每条语句的功能给看懂了,但从整体来看,对其实现过程细节,各个函数之间的关系,及客户端服务器中定义的管道文件及缓冲区在内存中的实现没有清晰的认识。总体来说,还是对管道通信本质的机制原理没有理解透彻,后来经过不断的查阅资料,对管道机制实现原理有了进一步的理解。 九、源程序代码1、管道通信#include#include#includeint pid1,pid2;main()int fd2;char OutPipe100,InPipe100;pip

31、e(fd); /创建管道while(pid1=fork()=-1);/创建子进程if(pid1=0)lockf(fd1,1,0);/给管道fd1所有字符上锁sprintf(OutPipe,child 1 process is sending message!n);write(fd1, OutPipe,50);/将OutPipe中的内容写入管道fd1sleep(5);lockf(fd1,0,0);/解锁exit(0);/结束进程 else while(pid2=fork()=-1);if(pid2=0)lockf(fd1,1,0);sprintf(OutPipe,child 2 process

32、is sending message!n);write(fd1,OutPipe,50);sleep(5);lockf(fd1,0,0);exit(0); else wait(0);read(fd0,InPipe,50);printf(%sn,InPipe);wait(0);read(fd0,InPipe,50);printf(%sn,InPipe);exit(0);2、服务端程序#define my_fifo my_fifo#define file_name server.#include#include#include#includevoidterminate();intwell_known

33、_id,tmp_id;chartmp_fil100;main(int argc,char *argv)intfd1,fd2;pid_tpid;charmy_buf100,my_fil100,my_tmp100;sprintf(my_buf,rm -f %s /dev/null,my_fifo);system(my_buf);/do shell cmd rm -f my_fifo /dev/nullwell_known_id=tmp_id=-1;signal(SIGINT,terminate);/通过调用sigint结束函数if(mkfifo(my_fifo,S_IRWXU|S_IRWXG|S_

34、IRWXO)=-1)/创建命名管道文件fprintf(stderr,Create Well_known FIOF Error!n);exit(-1);fprintf(stderr,mkfifo OK!n);fprintf(stderr,A New Seession! Im waiting connection.n);loop1:if(fd1=open(my_fifo,0)=-1)/将文件标识返回给fd1fprintf(stderr,Open well_known FIFO for readind Error!n);unlink(my_fifo);exit(-2); well_known_id=

35、fd1;tmp_id=-1;fprintf(stderr,open my_fifo OK!n);if(read(fd1,my_buf,20)!=0)/将fd1中的内容读到my_buf中fprintf(stderr,My_buff=%sn,my_buf);strcpy(my_fil,file_name);strncat(my_fil,my_buf,5);strcpy(tmp_fil,my_fil);if(pid=fork()!=0)close(fd1);wait();goto loop1;fprintf(stderr,Tmp_FIFO is: %s|n,my_fil);if(mkfifo(my_

36、fil,S_IRWXU|S_IRWXG|S_IRWXO)=-1)fprintf(stderr,Create my_fil:%s FIFO Error!n,my_fil);exit(-1); /system(ls server*);if(fd2=open(my_fil,2)=-1)fprintf(stderr,Open %s Error!:%dn,my_fil,fd2);close(fd1); unlink(my_fifo);exit(-3);tmp_id=fd2;if(write(fd2,my_buf,5)!=5)fprintf(stderr,Write %s Error!n,my_fil);

37、close(fd2); close(fd1);unlink(my_fil); unlink(my_fifo);exit(-4);sleep(1);if(read(fd2,my_tmp,5)!=5)fprintf(stderr,read %s Error!n,my_fil);close(fd2); close(fd1);unlink(my_fil); unlink(my_fifo);exit(-5);else if(strncmp(my_tmp,00000,5)!=0)close(fd2);close(fd1);fprintf(stderr,Filed to finish talking wit

38、h %s!n,my_fil);unlink(my_fil);exit(-1);/goto loop1;elseclose(fd2);close(fd1);fprintf(stderr,OK to talking with %s!n,my_fil);unlink(my_fil);/unlink(my_fifo);exit(0);void terminate()if(well_known_id!=-1)close(well_known_id); unlink(my_fifo);if(tmp_id!=-1)close(tmp_id);unlink(tmp_fil);fprintf(stderr,Th

39、e Server Program stoped by Signal:SIGINT!n);exit(0);3、客户端程序#define my_fifo my_fifo#define file_name server.#include#include#includemain(int argc,char *argv)intfd1,fd2,pid,pid1;charmy_buf100;charmy_fil100;charmy1buf100;if(fd1=open(my_fifo,1)=-1)fprintf(stderr,Open well_known FIFO for readind Error!n)

40、;exit(-1); fprintf(stderr,Open %s OK!n,my_fifo);pid=getpid();sprintf(my_buf,%5.5d%6.6d%7.7d,pid,pid*10,pid*20);if(write(fd1,my_buf,20)!=0)strcpy(my_fil,file_name);strncat(my_fil,my_buf,5);fprintf(stderr,Send_fil: %sn,my_fil);sleep(2);if(fd2=open(my_fil,2)=-1)fprintf(stderr,open %s Error!n,my_fil);close(

版权声明:以上文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如有侵权请立即联系:2622162128@qq.com ,我们立即下架或删除。

Copyright© 2022-2024 www.wodocx.com ,All Rights Reserved |陕ICP备19002583号-1 

陕公网安备 61072602000132号     违法和不良信息举报:0916-4228922