操作系统lab3

操作系统lab3

一、fork进程的执行控制
要求:通过fork的方式,产生4个进程P1,P2,P3,P4,每个进程打印输出自己的名字,例如P1输出“I am the process P1”。要求P1最先执行,P2、P3互斥执行,P4最后执行。通过多次测试验证实现是否正确。

添加互斥锁,使P2和P3互斥执行,等待P2和P3都完成后再执行P4进程,每个进程结束后返回。

操作系统lab3

操作系统lab3

操作系统lab3

二、对比非同步进程和同步进程
要求:火车票余票数ticketCount 初始值为1000,有一个售票线程,一个退票线程,各循环执行多次。添加同步机制,使得结果始终正确。要求多次测试添加同步机制前后的实验效果。

操作系统lab3

操作系统lab3

操作系统lab3

售票线程在每次售票前需要检查票是否还有余量,退票线程在每次退票前需检查是否有票售出。
同步机制能够有效的避免由于并发操作而导致的票总数出错的问题(即使得售票量+退票量始终为1000)。

三、生产者和消费者同步问题
要求:一个生产者一个消费者线程同步。设置一个线程共享的缓冲区, char buf[10]。一个线程不断从键盘输入字符到buf,一个线程不断的把buf的内容输出到显示器。要求输出的和输入的字符和顺序完全一致。在输出线程中,每次输出睡眠一秒钟,然后以不同的速度输入测试输出是否正确。要求多次测试添加同步机制前后的实验效果。

操作系统lab3

操作系统lab3

较慢输入,输出正确

操作系统lab3

两个一组较快输入,输出正确

四、进程通信问题。阅读并运行共享内存、管道、消息队列三种机制的代码
参考资料:
https://www.cnblogs.com/Jimmy1988/p/7706980.html
https://www.cnblogs.com/Jimmy1988/p/7699351.html
https://www.cnblogs.com/Jimmy1988/p/7553069.html
实验测试a)通过实验测试,验证共享内存的代码中,receiver能否正确读出sender发送的字符串?

操作系统lab3

共享内存的代码中,receiver能正确读出sender发送的字符串。

如果把其中互斥的代码删除,观察实验结果有何不同?

sender.c中的互斥代码为:

操作系统lab3

receiver.c中的互斥代码为:

操作系统lab3

代码中根据value = semctl(sem_id, 0, GETVAL),value的值为1时进行读,为0时进行写,实现互斥。

将其删掉再次运行:

操作系统lab3

可看到,第一次在sender还未输入数据时,receiver已经输出为空(空是因为上一次没有输入),错误。

如果在发送和接收进程中打印输出共享内存地址,他们是否相同,为什么?

共享内存地址相同,因为共享内存空间与代码无关,它是在系统中独立存在;

b)有名管道和无名管道通信系统调用是否已经实现了同步机制?通过实验验证,发送者和接收者如何同步的。比如,在什么情况下,发送者会阻塞,什么情况下,接收者会阻塞?

无论是无名管道还是有名管道,如果在读端和写端同时打开了多个进程用于读写,它们之间的读写是不确定的,必须通过其他的同步机制实现多进程通讯的同步,所以有名管道和无名管道并没有实现同步机制。

无名管道:

操作系统lab3

有名管道

操作系统lab3

c)消息通信系统调用是否已经实现了同步机制?通过实验验证,发送者和接收者如何同步的。比如,在什么情况下,发送者会阻塞,什么情况下,接收者会阻塞?

消息队列支持双向通信,克服了管道只能承载无格式字节流的缺点,在进程间只有少量数据传输的前提下实现了同步机制。

操作系统lab3

5)阅读Pintos操作系统,找到并阅读进程上下文切换的代码,说明实现的保存和恢复的上下文内容以及进程切换的工作流程。

进程切换就是从正在运行的进程中收回处理器,然后再使待运行进程来占用处理器。所谓从某个进程收回处理器,实质上就是将此进程存放在处理器的寄存器中的数据暂时存储起来,从而让其他进程使用寄存器。被中止运行进程的中间数据将被保存在进程的私有堆栈中让其他进程来占用处理器,实质上是把某个进程存放在私有堆栈中寄存器的数据(前一次此进程被中止时的数据)再恢复到处理器的寄存器中去,并把待运行进程的断点送入处理器的程序指针,于是待运行进程就开始被处理器运行了,即此进程已占有处理器的使用权了。

一个标准的Linux内核可以支持运行50~50000个进程运行,对于普通的CPU,内核会调度和执行这些进程。每个进程都会分到CPU的时间片来运行,当一个进程用完时间片或者被更高优先级的进程抢占后,它会备份到CPU的运行队列中,同时其他进程在CPU上运行。这个进程切换的过程被称作上下文切换。
在切换时,一个进程存储在处理器各寄存器中的中间数据叫做进程的上下文,所以进程的切换实质上就是被中止运行进程与待运行进程上下文的切换。在进程未占用处理器时,进程的上下文是存储在进程的私有堆栈中的。
本次实验代码已上传至
https://github.com/waguyu/waguyu/blob/master/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9FLab3%E6%BA%90%E4%BB%A3%E7%A0%81.docx