nachosLab8实习报告.docx

上传人:b****6 文档编号:8191713 上传时间:2023-01-29 格式:DOCX 页数:8 大小:498.42KB
下载 相关 举报
nachosLab8实习报告.docx_第1页
第1页 / 共8页
nachosLab8实习报告.docx_第2页
第2页 / 共8页
nachosLab8实习报告.docx_第3页
第3页 / 共8页
nachosLab8实习报告.docx_第4页
第4页 / 共8页
nachosLab8实习报告.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

nachosLab8实习报告.docx

《nachosLab8实习报告.docx》由会员分享,可在线阅读,更多相关《nachosLab8实习报告.docx(8页珍藏版)》请在冰豆网上搜索。

nachosLab8实习报告.docx

nachosLab8实习报告

通信机制实习报告

 

内容一:

总体概述

本次lab的主要内容是实现线程之间的消息传递,主要分为理论和实践两个部分,理论方面,我们需要了解Linux消息传递机制,实践方面,我们需要利用nachos模拟Linux消息传递机制并进行相关测试。

内容二:

任务完成情况

任务完成列表(Y/N)

Exercise1

Exercise2

Exercise3

Y

Y

Y

具体Exercise的完成情况

本实习希望通过修改Nachos系统平台的底层源代码,达到“实现通信机制”的目标。

Exercise1调研Linux中进程通信机制的实现

Linux中进程通信机制主要包括消息传递,共享内存,管道和套接字

(1)消息传递

消息传递通过消息缓冲区实现。

消息缓冲区是消息的链表,有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。

Linux维护消息队列向量表(msgque)表示系统中所有的消息队列。

消息克服了信号信息少,管道只能支持无格式字节流和缓冲区受限的缺点。

(2)共享内存

相互通信的进程间需要建立公共内存区域,来实现进程间的信息交换。

进程可以向该共享内存区域写也可以从该共享内存区域读。

共享内存是最快的IPC机制,但由于linux本身不能实现对其同步控制,需要用户程序进行并发访问控制,因此它一般结合了其他通信机制实现了进程间的通信,例如信号量。

(3)管道

管道是Linux支持的最初IPC方式,利用缓冲传输介质(内存或文件)连接两个相互通信的进程,管道可分为无名管道和有名管道。

  无名管道是半双工的,只能支持数据的单向流动,两进程间需要通信时需要建立起两个管道。

无名管道使用pipe()函数创建,只能用于父子进程或者兄弟进程之间。

管道对于通信两端进程而言,实质上是独立的文件,只存在于内存中。

一个进程向管道中写数据,所写的数据添加在管道缓冲区的尾部,另一个进程在管道中缓冲区的头部读数据。

  有名管道也是半双工的,不过它允许没有亲缘关系的进程间进行通信。

具体点说就是,有名管道提供了一个路径名与之进行关联,以FIFO(先进先出)的形式存在于文件系统中。

这样即使是不相干的进程也可以通过FIFO相互通信,只要他们能访问已经提供的路径。

值得注意的是,只有在管道有读端时,往管道中写数据才有意义。

否则,向管道写数据的进程会接收到内核发出来的SIGPIPE信号,应用程序可以自定义该信号处理函数,或者直接忽略该信号。

(4)套接字

服务器:

创建一个套接字,并将其与本地地址/端口号绑定;监听;当捕获到一个连接请求后,接受并生成一个新的套接字,调用recv()/send()与客户端通信,最后关闭新建的套接字

客户端:

为请求服务也创建一个套接字,并将其与本地地址/端口号绑定;指定服务器端的地址和端口号,并发出套接字连接请求;当请求被接受后,调用recv()/send()与服务器通信,最后关闭套接字连接

 

Exercise2为Nachos设计并实现一种线程/进程间通信机制

基于已完善的线程、调度、同步机制部分,选择Linux中的一种进程通信机制,在Nachos上实现

我选择实现管道和消息传递

管道

基本思路是添加函数WritePipe向管道写数据,添加函数ReadPipe从管道读数据。

注意到管道需要指明发送进程和接收进程,我选择通过文件名标记发送进程和接收进程,文件名的格式是pipe_发送进程ID_接收进程ID

WritePipe函数的基本流程是获得文件名,建立管道文件,向管道文件写入数据,设置管道文件长度,如果文件已经存在,说明通信进程存在消息没有接收,那么返回错误信息。

如果希望消息能够积累,那么可以将消息写入文件末尾。

注意到我们已经,实现文件长度的扩展和动态调整,管道的容量是有保证的

ReadPipe函数的基本流程是获得文件名,打开管道文件,确定管道文件长度,从管道文件读取数据。

如果文件不存在,那么通信进程没有消息需要接收,返回错误信息。

接收信息完成,通信过程结束,需要删除相应的管道文件。

尝试读出的数据数量根据管道文件长度确定,返回值是实际读出的数据数量

消息传递

基本思路是设置全局变量模拟消息缓冲区

修改thread.h,定义消息数据结构,消息项通过接收消息线程的线程ID记录消息目的地,通过字符串指针记录消息内容

structMessage{

boolvalid;//消息是否有效

intdestination;//消息目的地

char*content;//消息内容

};

修改system.h,定义消息缓冲区

externmessagemessage[20];

修改system.cc,初始化消息缓冲区

messagemessage[20];

for(inti=0;i<20;i++)

Message[i].valid=FALSE;

Send函数基本功能是发送消息,基本流程是检查消息缓冲区,如果存在空的消息项,那么将消息填入空的消息项,返回TRUE,说明消息发送成功,否则返回FALSE,说明没有空的消息项,消息发送失败

Receive函数基本功能是接收消息,基本流程是检查消息缓冲区,如果存在有效的消息项且消息项的目的地是当前线程,那么返回消息项内容,将消息项设为无效,如果不存在符合条件的消息项,那么返回NULL

 

Exercise3为实现的通信机制编写测试用例

管道

基本思路是建立参数-pipe调用PipeTest函数进行测试,PipeTest函数的基本流程是根据输入向管道写入数据(信息的目的地是建立的新线程),建立新线程,新线程调用函数PipeTestChild输出管道数据,然后新线程执行。

需要说明的是,实习1实现线程ID时,线程ID在线程构造函数时进行分配,所以线程Fork前可以获得线程ID

结果如下,线程0输入hello,线程1输出hello,线程通信顺利实现

消息传递

基本思路是建立参数-message调用MessageTest函数进行测试,MessageTest函数的基本流程是根据输入构造消息,将消息写入消息缓冲区,建立新线程,新线程调用函数MessageTestChild输出消息信息。

这里加入部分检验,发送消息的线程保证消息发送成功完成,接收消息的线程保证存在应该接收的消息,如果不满足这样的条件,那么返回错误

结果如下,线程0输入hello,线程1输出hello,线程通信顺利实现

内容三:

遇到的困难以及解决方法

困难:

保证消息在特定的两个线程间单向传递

我选择的方法是通过线程id识别两个通信线程

实现管道时,通过特定的文件名保证发送信息的线程和接收信息的线程是两个通信线程。

发送消息时,如果相应的管道文件已经存在,证明两个通信进程存在没有接收的信息,那么可以选择返回错误信息或将新的信息添加到文件的结尾,接收信息时,如果不存在相应的管道文件,证明两个通信线程不存在没有接收的信息,那么返回错误信息。

实现消息传递时,通过消息数据结构的相关信息记录接收线程线程id,发送消息的线程需要通过消息项纪录接收线程线程id,接收线程根据当前线程线程id确定应该接收的消息

内容四:

收获及感想

通过本学期的学习,我锻炼了编程能力,加深了对操作系统相关知识的理解。

比较可惜的是本学期大作业截止得比较早,后面做的比较仓促

内容五:

对课程的意见和建议

我觉得课程形式好,互动强,使我受益匪浅。

我觉得课程形式好,互动强,使我受益匪浅。

助教认真负责,知识充分,为课程付出很多,助教辛苦了:

-D

内容六:

参考文献

[1]陈老师课件同步机制

[2]nachos中文教程

[3]

Lab7deadlock

[4]

通信和死锁实习报告

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1