进程的管道通信实验

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

*******************
实践教学
*******************
兰州理工大学
计算机与通信学院
2010年秋季学期
操作系统原理课程设计
题目:进程的管道通信实验
专业班级:计算机(n)班
姓名:桌面小箭头
学号:0123456789
指导教师:刘嘉
成绩:
目录
前言 (3)
摘要 (4)
正文 (5)
1.设计思想 (5)
2.函数的关系调用图 (7)
3.相关的各模块的伪码算法 (8)
4.测试结果 (9)
5.源程序(带注释) (10)
总结 (13)
参考文献 (14)
致谢 (15)
附件Ⅰ部分源程序代码 (16)
前言
通过该题目的设计过程,了解什么是管道,熟悉UNIX/LINUX支持的管道通信方式。

了解UNIX的命令及使用格式,熟悉UNIX/LINUX的常用基本命令,练习并掌握UNIX提供的vi编辑器来编译C程序,学会利用gcc、gdb编译、调试C程序。

编写程序实现进程的管道通信。

用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话:
Child 1 is sending a message!
Child 2 is sending a message!
父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,后P2)。

通过实践设计对操作系统的了解进一步加强,同时加深了对C语言以及vi编译器的熟悉和理解。

此外,将所学的课本理论知识再次运用到实践当中,做到理论与实践相结合,得到软件工程的综合训练,提高解决实际问题的能力。

摘要
所谓管道,是指能够连接一个写进程和一个读进程的、同时允许它们以生产者-——消费者方式进行通信的一个共享文件,又称为pipe文件。

由写进程从管的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据
关键词:父进程,读写进程,管道,通信,文件
正文
1.设计思想
1.管道的创建:
#include <unistd.h>
int pipe(int fd[2])
该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义,因此,一个进程在由pipe()创建管道后,一般再fork一个子进程,然后通过管道实现父子进程间的通信(因此也不难推出,只要两个进程中存在亲缘关系,这里的亲缘关系指的是具有共同的祖先,都可以采用管道方式来进行通信)。

2.管道的读写规则:
管道两端可分别用描述字fd[0]以及fd[1]来描述,需要注意的是,管道的两端是固定了任务的。

即一端只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端。

如果试图从管道写端读取数据,或者向管道读端写入数据都将导致错误发生。

一般文件的I/O 函数都可以用于管道,如close、read、write等等。

(1)从管道中读取数据:
如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数为0;
当管道的写端存在时,如果请求的字节数目大于PIPE_BUF,则返回管道中现有的数据字节数,如果请求的字节数目不大于PIPE_BUF,则返回管道中现有数据字节数(此时,管道中数据量小于请求的数据量);或者返回请求的字节数(此时,管道中数据量不小于请求的数据量)。

(2)向管道中写入数据:
向管道中写入数据时,linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。

如果读进程不读走管道缓冲区中的数据,那么写操作将一直阻塞。

注:只有在管道的读端存在时,向管道中写入数据才有意义。

否则,向管道中写入数据的进程将收到内核传来的SIFPIPE信号,应用程序可以处理该信号,也可以忽略(默认动作则是应用程序终止)。

3,实验目的:
1、了解UNIX的命令及使用格式,熟悉UNIX/LINUX的常用基本命令,练
习并掌握UNIX提供的vi编辑器来编译C程序,学会利用gcc、gdb编译、调试C程序。

2、编写程序实现进程的管道通信。

用系统调用pipe( )建立一管道,二个子进程P1和P2分别向管道各写一句话:
Child 1 is sending a message!
Child 2 is sending a message!
父进程从管道中读出二个来自子进程的信息并显示(要求先接收P1,后P2)。

2.函数的关系调用图
3.相关的各模块的伪码算法
1,pipe()
建立一无名管道。

系统调用格式
pipe(filedes)
参数定义
int pipe(filedes);
int filedes[2];
其中,filedes[1]是写入端,filedes[0]是读出端。

该函数使用头文件如下:
#include <unistd.h>
#inlcude <signal.h>
#include <stdio.h>
2、read( )
系统调用格式
read(fd,buf,nbyte)
功能:从fd所指示的文件中读出nbyte个字节的数据,并将它们送至由指针buf所指示的缓冲区中。

如该文件被加锁,等待,直到锁打开为止。

参数定义
int read(fd,buf,nbyte);
int fd;
char *buf;
unsigned nbyte;
3、write( )
系统调用格式
read(fd,buf,nbyte)
功能:把nbyte 个字节的数据,从buf所指向的缓冲区写到由fd所指向的文件中。

如文件加锁,暂停写入,直至开锁。

参数定义同read( )。

4、sprintf( )
格式化字符串复制。

系统调用格式
sprintf(str, format )
功能:根据参数format 字符串来转换并格式化数据,然后将结果复制到参数str所指的字符串数组,直到出现字符结束(‘\0’)为止。

参数定义:
int sprintf(str,format)
char *st ;
const char *format ;
4.测试结果
5.源程序(带注释)
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
int main(void)
{
pid_t pid1;
pid_t pid2;
int fields[2];
char buffer[80];
char s[100];
char ss[100];
if(pipe(fields)!=0)
{
fprintf(stderr,"Createpipe error: %s\n\a",strerror(errno));
exit(1);
}
if((pid1 = fork() )< 0 )
printf("fork child1 error!\n");
else if( pid1==0 )
{
printf("fork child1 !\n");
close(fields[0]);
char s[]= " Child 1 is sending a message!\n";
write(fields[1],s,sizeof(s));
}
else if((pid2=fork())<0)
printf("fork child2 error!\n");
else if( pid2 == 0 )
{ printf ("fork child2 !\n");
close(fields[0]);
char ss[] = " Child 2 is sending a message!\n";
write(fields[1],s,strlen(s));
write(fields[1],ss,strlen(ss));
}
else{
printf("parent!\n");
close(fields[1]);
read(fields[0], buffer,80); printf("%s", buffer);}
exit (0);
}
总结
通过这次实践设计,使我对操作系统的了解进一步加强,同时加深了对C语言以及vi编译器的熟悉和理解。

此外,将所学的课本理论知识再次运用到实践当中,做到了理论与实践相结合,得到了软件工程的综合训练,提高了解决实际问题的能力。

做课设不仅让我修补了以前学习的漏洞,也让我知道一个道理:编程需要兴趣和实际动手。

这应该可以借鉴在老师的教学工作上。

创新思维至关重要,这不仅让我们写出精简的代码,也有助于开发出高效的程序。

经两个星期的设计和开发,进程的管道通信实验基本完成。

其功能基本符合课设需求。

当然,在本次实践设计中有遇到了不少困难,这说明对理论知识还不能深入地理解和灵活的运用,还有待于加强对课本知识的掌握。

此外,多加实践训练也是非常重要的。

这就要求我们在平时上机训练时对书本上的理论知识要亲手调试一遍,提高自己的实际动手能力,并在此过程中对发现的问题要多加思索,做到心领神会。

通过该题目的设计过程,可以加深理解操作系统,Linux操作系统以及进程的管道通信,进一步理解和熟练掌握课本中所学的有关操作系统的知识,学会如何把学到的知识用于解决实际问题,培养动手能力。

参考文献
1. 汤子瀛,哲凤屏.《计算机操作系统》.西安电子科技大学学出版社.
2. 王清,李光明.《计算机操作系统》.冶金工业出版社.
3.孙钟秀等.《操作系统教程》. 高等教育出版社
4.曾明.《Linux操作系统应用教程》. 陕西科学技术出版社.
5. 张丽芬,刘利雄.《操作系统实验教程》. 清华大学出版社.
6. 孟静.《操作系统教程--原理和实例分析》. 高等教育出版社
7. 周长林.《计算机操作系统教程》. 高等教育出版社
8. 张尧学.《计算机操作系统教程》.清华大学出版社
9. 任满杰.《操作系统原理实用教程》.电子工业出版社
致谢
这次课程设计使我学到了很多东西,真正做到了理论与实践相结合,得到了软件工程的综合训练,大大地提高了解决实际问题的能力。

当然,这与老师的指导和同学们的帮助是分不开的。

在此我要诚心感谢王旭阳老师的耐心指导,她对工作认真负责的态度以及严谨治学的精神和深厚的理论水平深深影响了我。

在整个设计过程当中给我提出了很多意见,并指出了许多错误和不足之处,使我受益匪浅。

为她付出了个人的宝贵时间来辅导我们而表示忠心的感谢!还要感谢我们班的同学,他们在这次设计当中给了我很多帮助,没有他的帮助这次的课设是不可能顺利完成的。

同时还要感谢孙钟秀,汤子瀛及张尧学等教授的书籍,为我提供了不少资料,使得这次设计能够按时完成。

在他们的帮助下不仅完成了这次课程设计,同时也学到了不少东西,在此再次感谢他们对我的帮助和支持!
附件Ⅰ部分源程序代码
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
int main(void)
{
pid_t pid1;
pid_t pid2;
int fields[2];
char buffer[80];
char s[100];
char ss[100];
if(pipe(fields)!=0)
{
fprintf(stderr,"Createpipe error: %s\n\a",strerror(errno)); exit(1);
}
if((pid1 = fork() )< 0 )
printf("fork child1 error!\n");
else if( pid1==0 )
{
printf("fork child1 !\n");
close(fields[0]);
char s[]= " Child 1 is sending a message!\n";
write(fields[1],s,sizeof(s));
}
else if((pid2=fork())<0)
printf("fork child2 error!\n");
else if( pid2 == 0 )
{ printf ("fork child2 !\n");
close(fields[0]);
char ss[] = " Child 2 is sending a message!\n";
write(fields[1],s,strlen(s));
write(fields[1],ss,strlen(ss));
}
else{
printf("parent!\n");
close(fields[1]);
read(fields[0], buffer,80); printf("%s", buffer);}
exit (0);
}。

相关文档
最新文档