课程设计实训报告书.docx
- 文档编号:2470817
- 上传时间:2022-10-29
- 格式:DOCX
- 页数:11
- 大小:533.68KB
课程设计实训报告书.docx
《课程设计实训报告书.docx》由会员分享,可在线阅读,更多相关《课程设计实训报告书.docx(11页珍藏版)》请在冰豆网上搜索。
课程设计实训报告书
九江学院
信息科学与技术学院
《嵌入式应用开发》课程设计
报告书
题目:
有名管道通信
专业:
计算机应用技术
班级:
B1232
姓名:
邓亲超
学号:
03
同组人员:
谢辉、张想、周政拉、毛扎西
指导老师:
周红波
设计时间:
2014年10月27日~2014年11月07日
2.问题描述
1.通过编写有名管道多路通信实验,进一步掌握管道的创建、读写等操作,同时复习使用select()函数实现管道的通信。
2.采用管道函数创建有名管道(并不是在控制台下输入命令),而且使用select()函数替代poll()函数实现多路复用(使用select()函数式处于以演示为目的)。
3.问题分析
用select()函数创建两个有名管道,并对相关文件描述符做相应操作。
两个有名管道中输入内容可以再终端显示出来,所以有名管道用只读非阻塞的方式打开,并且需要一个标准输入来判定,输入某个字符时可以立即结束程序。
并且设定一个倒计时,超时后同样立即结束程序。
循环测试有效的文件描述符是否存在,若不存在也将立即结束程序。
4.业务逻辑
实验先使用mkfifo()函数创建两个有名管道,来获得3个文件描述符,其中有两个有名管道和一个标准输入。
然后以非阻塞的方式打开两个管道文件,取出两个文件中描述符较大者,然后初始化读集inset,并在读文件描述符集中加入相应的描述集。
判断有效的文件描述符是否存在,并调用select()函数对文件描述符做相应操作,用tmp_inset=inset来重置读文件描述符集,这时在两个管道的窗口输入内容,都会显示在主程序上面,在终端输入“q”或“Q”时,将结束程序运行。
5.程序模块设计
源代码:
/*创建两个有名管道*/
if(access(FIFO1,F_OK)==-1)
{
if((mkfifo(FIFO1,0666)<0)&&(errno!
=EEXIST))
{
printf("Cannotcreatefifofile\n");
exit
(1);
}
}
if(access(FIFO2,F_OK)==-1)
{
if((mkfifo(FIFO2,0666)<0)&&(errno!
=EEXIST))
{
printf("Cannotcreatefifofile\n");
exit
(1);
}
}
/*以只读非阻塞方式打开两个管道文件*/
if((fds[1]=open(FIFO1,O_RDONLY|O_NONBLOCK))<0)
{
printf("Openin1error\n");
return1;
}
if((fds[2]=open(FIFO2,O_RDONLY|O_NONBLOCK))<0)
{
printf("Openin2error\n");
k9return1;
}
/*取出两个文件描述符中的较大者*/
maxfd=MAX(MAX(fds[0],fds[1]),fds[2]);
/*初始化读集合inset,并在读文件描述符集合中加入相应的描述集*/
FD_ZERO(&inset);
for(i=0;i { FD_SET(fds[i],&inset); } FD_SET(0,&inset); tv.tv_sec=TIME_DELAY; tv.tv_usec=0; /*循环测试该文件描述符是否准备就绪并调用select()函数对相关文件描述符做相应操作*/ while(FD_ISSET(fds[0],&inset)||FD_ISSET(fds[1],&inset)||FD_ISSET(fds[2],&inset)) { /*文件描述符集合的备份,免得每次进行初始化*/ tmp_inset=inset; res=select(maxfd+1,&tmp_inset,NULL,NULL,&tv) switch(res) {case-1: { printf("Selecterror\n"); return1;} break; case0: /*Timeout*/ {printf("Timeout\n"); return1;} break; default: {for(i=0;i if(FD_ISSET(fds[i],&tmp_inset){ memset(buf,0,MAX_BUFFER_SIZE); real_read=read(fds[i],buf,MAX_BUFFER_SIZE); if(real_read<0) {if(errno! =EAGAIN){ return1;}} elseif(! real_read) {close(fds[i]);FD_CLR(fds[i],&inset);} else {if(i==0){/*主程序终端控制*/ if((buf[0]=='q')||(buf[0]=='Q')) {return1;} }else {/*显示管道输入字符串*/ buf[real_read]='\0'; printf("%s",buf);}} }/*endofif*/ }/*endoffor*/} break; }/*endofswitch*/ }/*endofwhile*/ return0; } 6.技术原理与分析 如果一个进程为了从FIFO中读取数据而阻塞打开了FIFO,那么称该进程内的读操作为设置了阻塞标志的读操作。 如果有进程写打开FIFO,且当前FIFO为空,则对于设置了阻塞标志的读操作来说,将一直阻塞下去,直到有数据可以读时才继续执行;对于没有设置阻塞标志的读操作来说,则返回0个字节,当前errno值为EAGAIN,提醒以后再试。 对于设置了阻塞标志的读操作来说,造成阻塞的原因有两种: 一、当前FIFO内有数据,但有其它进程在读这些数据;二、FIFO本身为空。 当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性。 如果此时管道空闲缓冲区不足以容纳要写入的字节数,则进入睡眠,直到当缓冲区中能够容纳要写入的字节数时,才开始进行一次性写操作。 即写入的数据长度小于等于PIPE_BUF时,那么或者写入全部字节,或者一个字节都不写入,它属于一个一次性行为,具体要看FIFO中是否有足够的缓冲区。 当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。 FIFO缓冲区一有空闲区域,写进程就会试图向管道写入数据,写操作在写完所有请求写的数据后返回。 当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性。 如果当前FIFO空闲缓冲区能够容纳请求写入的字节数,写完后成功返回;如果当前FIFO空闲缓冲区不能够容纳请求写入的字节数,则返回EAGAIN错误,提醒以后再写。 当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。 在写满所有FIFO空闲缓冲区后,写操作返回。 7.系统测试 主要内容: 测试数据和测试结果。 8.心得体会 通过这次课程设计,本人在多方面都有所提高。 通过这次课程设计,综合运用本专业所学课程的理论,进行这次实训培养和提高学生独立思考能力,巩固与扩充了课程所学的内容,掌握有名通道的意义和用法。 熟悉了Linux的用法,同时复习了相关的课程,思考的能力也有了提高。 9.参考文献 1.李健,宋健建翻译。 Linux程序设计第三版。 人民邮电出版社。 2013。 11178-186 2.毛德操,胡希明,主编。 Linux内核源代码情景分析。 浙江大学出版社。 2012.456-61 3.韦东山,主编。 嵌入式Linux应用开发完全手册。 人民邮电出版社。 2008.8123-132 4.Halinan,C,著。 嵌入式Linux开发.人民邮电出版社。 2008.235-45
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 课程设计 报告书