资源描述
《计算机操作系统》课程设计报告
课程名称: 操作系统
设计题目: 管道通信
指导教师: *******
班 级: *******
学 号: *****
学生姓名: ***
同组人员: *******************
成 绩:
评 语:
计算机科学与工程学院
2014年6月19 日
前言:
Linux操作系统就是一个向用户开放源码得免费得类UNIX操作系统。它为在校学生学习操作系统课程提供了一个瞧得见摸得着得范例。对于学生正确理解,掌握操作系统得基本知识具有重要意义。鉴于此,本操作系统课程涉及得实验均在Linux环境下进行。
这就要求大家:
(1)熟悉Linux得操作与开发环境;
(2)具有C语言知识(Linux操作系统大约90%得源码就是用C语言编写)。
我们得设计与实验将在Windows xp环境下,基于虚拟机软件VMWare软件进行安装。
学习计算机软件技术,特别就是计算机操作系统技术,除了需要刻苦努力外,还需要掌握软件与操作系统得原理与设计技巧。如何学习与掌握操作系统技术得原理与实际技巧呢?除了听课与读书之外,最好得方法恐怕就就是在实践中练习。例如,自己设计一个小型操作系统,多使用操作系统,多阅读与分析操作源代码等。但由于我们得条件与学时有限,在理论学习过程中没有给同学们提供更多得实验机会.
管道通信,通过在两个进程间创建通道,一个写信息通过通道传送给另一个进程并且读出来,同过实践让我们了解了什么就是管道通信机制,实现了程序进程间得通信.积极通过合作,完成任务。
目 录
第一章 :系统环境 4
1、1硬件环境 4
1、2软件环境ﻩ4
第二章 :设计目得 4
第三章 :总体设计 5
3、1程序设计组成框图ﻩ5
3、2流程图ﻩ6
3、2、1匿名管道通信C/S流程图ﻩ6
3、2、2命名管道通信C/S流程图ﻩ6
第四章 :详细设计ﻩ8
4、1匿名管道通信 8
4、2命名管道通信ﻩ10
第五章 :调试与测试 13
第六章 :设计中遇到得问题及解决方法ﻩ15
第七章 :源程序清单与执行结果及分析ﻩ16
第八章 :总结 20
第九章 :参考文献ﻩ20
第一章 :系统环境
1、1硬件环境
Intel(R)Core™2 Duo CPU E7500 2、93GHz 2、00GB内存
1、2软件环境
1)Microsoft Windows XP Professional 版本2002 Service Pack 3
2)Vmware Workstation 10、0、1 build—1379776
3)Red Hat Linux 9
第二章 :设计目得
实践操作系统原理知识,根据题目要求设计、实现进程得管道通信,并且在虚拟机中模拟得linux系统中运行检测。
第三章 :总体设计
3、1程序设计组成框图
无名管道读写示意图
命名管道操作示意图
3、2流程图
3、2、1匿名管道通信C/S流程图
3、2、2命名管道通信C/S流程图
FIFO写进程:
第四章 :详细设计
4、1匿名管道通信
管道用于不同进程间通信。通常先创建一个管道,再通过fork函数创建一个子进程,该子进程会继承父进程创建得管道。注意事项:必须在系统调用fork()前调用pipe(),否则子进程将不会继承文件描述符。否则,会创建两个管道,因为父子进程共享同一段代码段,都会各自调用pipe(),即建立两个管道,出现异常错误。 父进程通过管道向服务器发布命令,然后由服务器执行命令.
1、fork()
创建一个新进程.
用法: int fork()
其中返回int取值意义如下:
0:创建子进程,从子进程返回得id值
〉0:从父进程返回得子进程id值
—1:创建失败
2、lockf()
用作锁定文件得某些段或者整个文件.
头文件:
#includeﻩ<unistd、h>
参数定义:
int lockf();
int ;
long size;
其中:files就是文件描述符;function就是锁定与解锁;1表示锁定;0表示解锁;Size就是锁定或解锁得字节数,若用0,表示从文件得当前位置到文件尾。
3、read
功能:从描述符为得文件读信息。
用法:
#include <unistd、h>
ssize_t read(int , void *buff, size_t nbytes) ;
返回:读到得字节数,若已到文件尾为0,若出错为-1。
在UNIX/Linux 可重定义为:
intﻩread(int fd, char *buff, unsigned nbytes) ;
4、write
功能:向已打开得文件写数据.
用法:
#include <unistd、h〉
ssize_t write(int , const void * buff, size_t nbytes) ;
返回值:若成功为已写入得字节数;出错为-1.
intﻩwrite(int fd, char *buff, unsigned nbytes) ;
文件位置指针
文件位置指针:每个打开文件都有一个与其相关联得“当前位移量”.就是从文件开始处计算得字节数.通常,读、写操作都从当前文件位置处开始,并使位移量增加所读或写得字节数。
按系统默认,当打开一个文件时,除非指定O_APPEND选择项,否则该位移量被设置为0,即指向文件得开始处。
文件位置指针可以通过系统调用lseek来移动.
#include 〈unistd、h〉
#include 〈sys/types、h>
#include 〈errno、h〉
#include 〈stdio、h〉
#include <string、h〉
#include 〈stdlib、h〉
/*
* 程序入口
* */
int main()
{
int pipe_fd[2];
pid_t pid;
char buf_r[100];
char* p_wbuf;
int r_num;
memset(buf_r,0,sizeof(buf_r)); //对较大得结构体或数组进行清零操作得一种最快方法
/*创建管道*/
if(pipe(pipe_fd)<0)
{
printf(”pipe create error\n");
return —1;
}
/*创建子进程*/
if((pid=fork())==0) //子进程执行序列
{
printf("\n”);
close(pipe_fd[1]);//子进程先关闭了管道得写端
sleep(2); /*让父进程先运行,这样父进程先写子进程才有内容读*/
if((r_num=read(pipe_fd[0],buf_r,100))>0)
{
printf(”%d numbers read from the pipe is %s\n",r_num,buf_r);
}
close(pipe_fd[0]);
exit(0);
}
else if(pid>0) //父进程执行序列
{
close(pipe_fd[0]); //父进程先关闭了管道得读端
if(write(pipe_fd[1],"Hello",5)!=—1)
printf("parent write1 Hello!\n”);
if(write(pipe_fd[1]," Pipe”,5)!=—1)
printf(”parent write2 Pipe!\n");
close(pipe_fd[1]);
waitpid(pid,NULL,0); /*等待子进程结束*/
exit(0);
}
return 0;
}
4、2命名管道通信
命名管道 :
命名管道与无名管道基本相同,但也有不同点:无名管道只能有父进程使用;但就是通过命名管道,不相关得进程也能交换数据。客户机实现数据得发送,服务器实现数据接收。
1、创建
用mkfifo或mknod创建一个命名管道。以mkfifo为例:
ﻩ#includeﻩ<sys/types、h>
ﻩ#include <sys/stat、h>
ﻩint mkfifo(const char *fifo_name, mode_t mode); ﻩ//成功返回0,否则为—1
2、使用
管道一经创建,就可向普通文件一样使用.可通过系统调用open,close,read,write,unlink等进行操作。
FIFO读进程:
#include <sys/types、h>
#include 〈sys/stat、h>
#include <errno、h〉
#include <fcntl、h>
#include <stdio、h>
#include 〈stdlib、h〉
#include <string、h>
#define FIFO "myfifo"
/*程序入口*/
int main(int argc,char** argv)
{
char buf_r[100];
int fd;
int nread;
printf(”Preparing for reading bytes、、、\n");
memset(buf_r,0,sizeof(buf_r));
/*打开管道*/
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);
}
while(1)
{
memset(buf_r,0,sizeof(buf_r));
if((nread=read(fd,buf_r,100))==-1)
{
if(errno==EAGAIN)
printf(”no data yet\n”);
}
printf("read %s from FIFO\n",buf_r);
sleep(1);
}
/*后面三句话就是不会被运行到得,但不会影响程序运行得效果当程序在上面得死循环中执行时收到信号后会马上结束运行而没有执行后面得三句话。*/
close(fd); //关闭管道
pause(); //暂停,等待信号
unlink(FIFO); //删除文件
}
FIFO写进程:
#include <sys/types、h〉
#include <sys/stat、h>
#include 〈errno、h>
#include <fcntl、h>
#include 〈stdio、h〉
#include <stdlib、h〉
#include <string、h>
#define FIFO_SERVER "myfifo”
/*
* 程序入口
* */
int main(int argc,char** argv)
{
int fd;
char w_buf[100];
int nwrite;
/*创建有名管道*/
if((mkfifo(FIFO_SERVER,O_CREAT|O_EXCL|O_RDWR)<0)&&(errno!=EEXIST))
{
printf("cannot create fifoserver\n");
}
/*打开管道*/
fd=open(FIFO_SERVER,O_WRONLY |O_NONBLOCK,0);
if(fd==-1)
{
perror("open");
exit(1);
}
/*入参检测*/
if(argc==1)
{
printf("Please send something\n");
exit(—1);
}
strcpy(w_buf,argv[1]);
/* 向管道写入数据 */
if((nwrite=write(fd,w_buf,100))==-1)
{
if(errno==EAGAIN)
printf(”The FIFO has not been read yet、Please try later\n");
}
else
{
printf("write %s to the FIFO\n”,w_buf);
}
close(fd); //关闭管道
return 0;
}
第五章 :调试与测试
运行匿名管道通信以及运行命名管道通信读进程结果如下:
打开另外一个终端,运行写进程结果如下:
同时读进程结果发生变化如下:
第六章 :设计中遇到得问题及解决方法
1、 由于课程涉及UNIX管道通信模式较少,刚开始做课程设计时感觉无从下手,后来通过瞧书以及上网查询相关资料有些头绪。
2、对于虚拟机与主机得交互搞了好久但就是最后结果不理想,也没搞成功,试了用ftp方式相互连接,以及通过VMware Tools也没有成功。后来,通过问学长与同学终于解决了。通过此事,我知道知识自己主动探索实践固然好,但学习她人已有得经验学得知识更多更快。
3、对于C语言中open、write等函数掌握得并不好,这就是由于长期不联系C语言所致,一门语言要想精通必须通过不断得联系才行。
第七章 :源程序清单与执行结果及分析
任务1:匿名管道通信
#include <unistd、h〉
#include 〈sys/types、h>
#include 〈errno、h〉
#include 〈stdio、h>
#include 〈string、h〉
#include <stdlib、h>
/*
* 程序入口
* */
int main()
{
int pipe_fd[2];
pid_t pid;
char buf_r[100];
char* p_wbuf;
int r_num;
memset(buf_r,0,sizeof(buf_r));
/*创建管道*/
if(pipe(pipe_fd)〈0)
{
printf("pipe create error\n”);
return —1;
}
/*创建子进程*/
if((pid=fork())==0) //子进程执行序列
{
printf("\n");
close(pipe_fd[1]);//子进程先关闭了管道得写端
sleep(2); /*让父进程先运行,这样父进程先写子进程才有内容读*/
if((r_num=read(pipe_fd[0],buf_r,100))〉0)
{
printf(”%d numbers read from the pipe is %s\n”,r_num,buf_r);
}
close(pipe_fd[0]);
exit(0);
}
else if(pid>0) //父进程执行序列
{
close(pipe_fd[0]); //父进程先关闭了管道得读端
if(write(pipe_fd[1],”Hello”,5)!=—1)
printf("parent write1 Hello!\n”);
if(write(pipe_fd[1]," Pipe",5)!=—1)
printf("parent write2 Pipe!\n");
close(pipe_fd[1]);
waitpid(pid,NULL,0); /*等待子进程结束*/
exit(0);
}
return 0;
}
任务2:命名管道通信
FIFO读进程:
#include <sys/types、h>
#include 〈sys/stat、h〉
#include <errno、h〉
#include 〈fcntl、h>
#include <stdio、h>
#include <stdlib、h〉
#include <string、h>
#define FIFO ”/tmp/myfifo”
/*程序入口*/
int main(int argc,char** argv)
{
char buf_r[100];
int fd;
int nread;
printf(”Preparing for reading bytes、、、\n”);
memset(buf_r,0,sizeof(buf_r));
/*打开管道*/
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd==-1)
{
perror(”open”);
exit(1);
}
while(1)
{
memset(buf_r,0,sizeof(buf_r));
if((nread=read(fd,buf_r,100))==-1)
{
if(errno==EAGAIN)
printf("no data yet\n");
}
printf(”read %s from FIFO\n",buf_r);
sleep(1);
}
/*后面三句话就是不会被运行到得,但不会影响程序运行得效果当程序在上面得死循环中执行时收到信号后会马上结束运行而没有执行后面得三句话。*/
close(fd); //关闭管道
pause(); //暂停,等待信号
unlink(FIFO); //删除文件
}
FIFO写进程:
#include <sys/types、h〉
#include <sys/stat、h>
#include <errno、h>
#include 〈fcntl、h>
#include 〈stdio、h>
#include 〈stdlib、h>
#include 〈string、h〉
#define FIFO_SERVER ”/tmp/myfifo"
/*
* 程序入口
* */
int main(int argc,char** argv)
{
int fd;
char w_buf[100];
int nwrite;
/*创建有名管道*/
if((mkfifo(FIFO_SERVER,O_CREAT|O_EXCL|O_RDWR)<0)&&(errno!=EEXIST))
{
printf("cannot create fifoserver\n”);
}
/*打开管道*/
fd=open(FIFO_SERVER,O_WRONLY |O_NONBLOCK,0);
if(fd==-1)
{
perror(”open");
exit(1);
}
/*入参检测*/
if(argc==1)
{
printf(”Please send something\n”);
exit(—1);
}
strcpy(w_buf,argv[1]);
/* 向管道写入数据 */
if((nwrite=write(fd,w_buf,100))==-1)
{
if(errno==EAGAIN)
printf("The FIFO has not been read yet、Please try later\n”);
}
else
{
printf("write %s to the FIFO\n",w_buf);
}
close(fd); //关闭管道
return 0;
}
第八章 :总结
此次课程设计-管道通信,让我实实在在地锻炼了自己得动手能力,基本操作以熟练掌握。设计中地任务一比较简单,只就是设计一个程序实现管道通信,通过查资料可以顺利完成;但就是任务二—命名管道设计,涉及到了头文件、服务器程序与客户端程序,三者要在同一台计算机中,两个不同得终端上实现通信。服务器程序设计操作中没有出现什么问题,但就是在连接客户端程序时,客户端程序出错,编译出现错误,导致通信出现错误.通过向老师请教与同学询问,基本有些了解,但还就是出现一些解决不了得问题,还需要多加联系然后多查资料,认真克服困难。
通过这次课程设计,我感觉到了,编程还就是很有趣得一件事情,这次设计充分锻炼了我得动手能力,思维能力,设计能力,更重要得就是合作精神,大家基础都有点差,但可以主动找不足,主动查询资料,询问同学与请教老师,充分体现了新时代新青年得团结与探索精神。
第九章 :参考文献
汤小丹,梁红兵编著·《计算机操作系统》(第三版)·西安电子科技大学出版社,2007
展开阅读全文