操作系统课程设计报告
目录
实验一、Windows进程管理
1、实验目的
(1)学会使用 VC 编写基本的 Win32 Consol Application(控制台应用程序)。
(2)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操 作系统的进程概念,理解 Windows 进程的“一生”。
(3)通过阅读和分析实验程序,学习创建进程、观察进程、终止进程以及父子进程同步的基 本程序设计方法。
2、详细设计
(1)编写基本的 Win32 Consol Application
一开始运行不成功,因为分号,双引号等字符为中文字符。
(2) 创建进程
程序从main函数开始,创建进程,每次引用该进程exe文件位置创建下一个进程(再反过来继续调用main函数,如此循环,使用c_nCloneMax作为限制)并使得nCloneID+1显示当前进程ID
打开任务管理器可以看到这些进程正在运行:
第一次修改: 结果不变(如图)
第二次修改:
我的理解是:因为改变了nclone=0赋值语句的位置,在运行时,每次都会将nclone的值变为0,所以每次在运行下面的程序时:
// 检查是否有创建子进程的需要
const int c_nCloneMax=5;
if (nClone < c_nCloneMax)
{
// 发送新进程的命令行和克隆号
StartClone(++nClone) ;
}
nClone < c_nCloneMax会永远成立,所以永远不会达到限制条件5,变成死循环,一直不断的创建ID为0的新进程,直至溢出内存。
1、nClone 的作用:
控制ID的起始值,控制创建进程的数量。
2、变量的定义和初始化方法(位置)对程序的执行结果的有没有影响?
有影响,在修改变量的定义和初始化位置时,通过程序运行结果观察到,它们的改变引起了进程的创建数目的不同(循环次数有不同),也引起了ID的起始位置的变化
(3) 父子进程的简单通信及终止进程
步骤2运行结果如图
步骤三:将下句中的字符串 child 改为别的字符串, 重新编译执行。
sprintf(szCmdLine, "\"%s\"baby" , szFilename) ;
可以观察到,在创建子进程的之后,进入的不再是child函数,而是在循环执行parent函数,所以,程序在不断的创建子进程。
步骤四:
将INFINIT换成0,意味着子进程来不及等待父进程在释放互斥体之后发送过来的自杀指令,就自己执行了下面的自杀代码。
步骤 5 : 参考 MSDN 中 的 帮 助 文 件 CreateMutex() 、 OpenMutex() 、 ReleaseMutex() 和 WaitForSingleObject()的使用方法,理解父子进程如何利用互斥体进行同步的。
CreateMutex()是创建互斥体,OpenMutex()是打开互斥体,ReleqaseMutex()是释放互斥体,WaitForSingleObject()是检测hMutexSuicide事件的信号状态,通过这些方法可以实现当前只有一个进程被创建或被使用,实现进程的同步。
3、实验结果与分析
互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex))。互斥体禁止多个线程同时进入受保护的代码“临界区”(critical section)。因此,在任意时刻,只有一个线程被允许进入这样的代码保护区。任何线程在进入临界区之前,必须获取(acquire)与此区域相关联的互斥体的所有权。如果已有另一线程拥有了临界区的互斥体,其他线程就不能再进入其中。这些线程必须等待,直到当前的属主线程释放(release)该互斥体。
WaitForSingleObject函数用来检测hMutexSuicide事件的信号状态,在某一线程中调用该函数时 ,线程暂时挂起,如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hMutexSuicide所指向的对象还没有变成有信号状态,函数照样返回。 参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。
5、实验总结与体会
对互斥与同步有了简单的了解,熟练了在命令行运行代码的相关操作。虽然操作系统对我来说真的有点难度,但是我还是尽力在理解和掌握,希望能通过每一个实验都收获到一些知识。
实验二、Linux 进程管理
1、 实验目的
通过进程的创建、撤销和运行加深对进程概念和进程并发执行的理解,明确进程和程序之间的区别。
2、 总体设计
任务要求1: 编写一段程序,使用系统调用 fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“ a”;两子进程分别显示字符“ b”和字符“ c”。
任务要求2: 编写一段程序,使用系统调用 fork()创建一个子进程。子进程通过系统调用 exec更换自己原有的执行代码, 转去执行 Linux 命令/bin/ls (显示当前目录的列表),然后调用 exit()函数结束。父进程则调用 waitpid()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。
3、 详细设计
(1) 进程的创建
结果显示为bc ac
(2)子进程执行新任务
因为我新建的文档在桌面上,因此输出的结果显示了桌面上bin目录下的所有文件。当fork()函数返回值为0时,子程序可以通过调用exec()函数去执行要求的代码。
4、 实验小结与心得
fork()函数用来创建新进程,如成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID,否则,出错返回-1。Linux系统还是用的不太惯,不过,通过这次使用感觉还挺不错的,很方便,什么都能在终端实现,之前在自己电脑上安装了kali Linux,可能是电脑真的垃圾,就很慢,使用体验极差。
实验三、互斥与同步
1、实验目的
(1) 回顾操作系统进程、线程的有关概念,加深对 Windows 线程的理解。
(2) 了解互斥体对象,利用互斥与同步操作编写生产者-消费者问题的并发程序,加深对 P (即 semWait)、V(即 semSignal)原语以及利用 P、V 原语进行进程间同步与互斥操作的理解。
2、总体设计
详见《操作系统课程设计参考文档》
3、详细设计
(1)生产者消费者问题
步骤 1: 创建一个“Win32 Consol Application”工程,然后拷贝清单 3-1 中的程序,编译成可执行