【nachos】nachos学习笔记(三) 信号量和进程同步

一、实验题目

(a) Read ring.h and ring.cc and make sure that you understand everything in them.
(b) Read main.cc.
(c) Read prodcons++.cc and make sure that you understand
i. the structure of the program
ii. the task to complete the program
(d) Complete all programs in file prodcons++.cc.
(e) Compile a new nachos by command make and test if your program is working or not.
The output files of an example run of the problem with two consumers and two producers each of which produces four messages should be like this: 
• the contents of tmp 0: 
producer id --> 0; Message number --> 0; 
producer id --> 0; Message number --> 1; 
producer id --> 1; Message number --> 3;
• the contents of tmp 1: 
producer id --> 0; Message number --> 2; 
producer id --> 0; Message number --> 3;
producer id --> 1; Message number --> 0; 
producer id --> 1; Message number --> 1;
producer id --> 1; Message number --> 2;

  题目要求使用nachos提供的信号量机制编写一个生产者消费者程序。

二、分析

main函数中调用了ProdCons方法,如下

该方法负责初始化信号量,并且创建生产者和消费者线程。用到的信号量及其初始化如下:

创建一个长度为3的Ring用来存放信息。然后按题目要求分别创建2个生产者和消费者线程,生产者调用Producer函数产生信息,消费者调用Consumer函数提取信息。

生产者想要修改Ring时要确保Ring还没有装满,所以必须先对信号量nfull进行P操作,等待Ring有空位时继续执行。对ring进行put操作前,需先获取互斥锁,操作完成之后缩放互斥锁,同时对信号量nempty进行V操作。同样,消费者提取Ring中的信息时也要进行类似的操作,不再赘述。补全后的代码如下:

补全程序后make运行,可到相应目录的tmp_0和tmp_1中查看执行情况。

三、测试

  运行程序时,若不用-rs参数指定随机数种子,则每个线程执行时并不会自动调用Yield,这将导致所有生产者线程按线程生成的顺序生成信息,而所有信息都会被消费者1取走。若使用-rs参数提供种子,则消费和生成的顺序变为随机。为观察这一过程,在生成和消费的语句下方加入调试信息,测试结果如下:
不使用参数:

使用参数 -rs 12356

对应的tmp_0和tmp_1文件如下:

四、遇到的问题

由于consumer函数中调用了IO函数,所以若未引入头文件将产生编译错误。

五、Nachos线程实现探究

这次实验中,我对nachos如何模拟CPU线程存在疑问,于是对相关源码进行了阅读,并略有感悟,如有不对还请指正。

我的疑问如下:

1、Nachos并没有调用C++提供的创建线程的库,因为Nachos本意是模拟一个操作系统,是提供这些服务的对象,那么nachos是如何实现多线程的呢?

2、在以上实验中,我们使用-rs参数让nachos的线程随机Yield,这就需要一个线程执行过程中被中断请求终止,然后执行yield,真正的CPU在硬件级别上可以实现每执行一条指令去查看是否有中断请求,那么nachos如何在软件层次上实现这个功能?

首先,先看一下Thread这个对象的域里有哪些信息。

猜你喜欢

转载自blog.csdn.net/darord/article/details/83588850