高等学校计算机操作系统实验报告最终答案 - 图文 联系客服

发布时间 : 星期五 文章高等学校计算机操作系统实验报告最终答案 - 图文更新完毕开始阅读561c6d116c175f0e7cd13797

在进程间使用事件。父进程启动时,利用CreateEvent()API创建一个命名的、可共享的子进程,然后等待子进程向事件发出信号并终止父进程。在创建时,子进程通过OpenEvent()API打开事件对象,调用SetEvent()API使其转化为已接收信号状态。两个进程在发出信号之后几乎立即终止。

步骤1:登录进入Windows 2000 Professional。 步骤2:在“开始”菜单中单击“程序”、“Microsoft Visual Studio 6.0”“Microsoft Visual C++ 6.0”,进入Visual C++窗口。

步骤3:在工具栏单击“新建”按钮,编写代码保存为3-1.cpp。 程序功能:创建和打开事件对象在进程间传送信号。 参考类和函数:

windows.h、iostream、CreateChild()、szFilename、GetModuleFileName、 szCmdLine、CloseHandle、WaitForChild()。

步骤4:单击“Build”菜单中的“Compile 3-1.cpp”命令,单击“是”按钮确认,系统对3-1.cpp进行编译。

步骤5:编译完成后,单击“Build”菜单中的“Build3-1.exe”命令,建立3-1.exe可执行文件。

操作能否正常进行,如果不行,原因是什么? 解:程序能够正常执行。

步骤6:在工具栏单击“Execute program”按钮,执行3-1.exe程序。

运行结果(分行书写,如果不成功,原因是什么?): 在去掉:: Sleep(1500);之前的运行结果是: 1. event created 2. chlid created

3. Parent waiting on child. 4. child process begining...... 5. event signaled

6. parent received the envent signaling from child 7. Parent released. 去掉:: Sleep(1500);语句:

1. event created 2. chlid created

3. Parent waitingc on chhiildl. 4. d process begining......

5. eparvent erentceived the ensivegnt nsiganlalinge frd 6. om child

7. Parent released.

这个结果与你期望的一致吗?(从进程并发的角度对结果进行分析)。

分析可知:在有Sleep(1500);时,主程序会等待子程序1.5s,这样的话子程序先输出,然后主程序再输出。这样的话就不会出现错误。而当去掉:: Sleep(1500);语句之后主程序和字程序同时输出就会出现输出结果重叠的情况,变现为输出结果错误。 请回答:

1)程序中,创建一个事件使用了哪一个系统函数?创建时设置的初始信号状态是什么?

a)创建事件用CreateEvent()函数

b)CreateEvent( NULL, TRUE, FALSE, 始状态为有信号状态

g_szContinueEvent); // 事件名称,指定事件的对象的名称,是一个以0结束的字符串指针

// 缺省的安全性,子进程将具有访问权限

// 手工重置事件,必须用ResetEvent函数// 初始时是非接受信号状态,为TRUE,初

来手工将事件的状态复原到无信号状态

2)创建一个进程(子进程)使用了哪一个系统函数? 创建子进程使用

BOOL CreateProcess (

LPCTSTR lpApplicationName, //指向一个NULL结尾的、用来指定可执行模块的字符串。

LPTSTR lpCommandLine, //指向一个NULL结尾的、用来指定要运行的命令行。

LPSECURITY_ATTRIBUTES lpProcessAttributes。//指向一个结构体,这个结构体决定是否返回的句柄可以被子进程继承。

LPSECURITY_ATTRIBUTES lpThreadAttributes, //向一个结构体,这个结构体决定是否返回的句柄可以被子进程继承

BOOL bInheritHandles, //指示新进程是否从调用进程处继承了句柄。为真表示继承

DWORD dwCreationFlags,// 指定附加的、用来控制优先类和进程的创建的标志。

LPVOID lpEnvironment, //指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境。

LPCTSTR lpCurrentDirectory, //指向一个以NULL结尾的字符

串,这个字符串用来指定子进程的工作路径。如果这个参数为空,新进程将使用与调用进程相同的驱动器和目录。

LPSTARTUPINFO lpStartupInfo, //指向一个用于决定新进程的主窗体如何显示的STARTUPINFO结构体。

LPPROCESS_INFORMATION lpProcessInformation //指向一个用来接收新进程的识别信息的结构体。

);

WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件。

2. 互斥信号量对象

使用互斥信号量来保证对两个线程间单一数值的访问。每个线程都企图获得控制权来改变该数值,然后将该数值写入输出流中。创建者实际上创建的是互斥信号量对象,计数方法执行等待并释放,为的是共同使用互斥信号量所需的资源(因而也就是共享资源)。

步骤1:在工具栏单击“新建”按钮,编写代码保存为3-2.cpp。 程序功能:利用互斥信号量保护共享资源

参考类与函数:windows.h、iostream、class CCountUpDown、 WaitForCompletion()、DoCount()、ReleaseMutex()、

步骤2:单击“Build”菜单中的“Compile 3-2.cpp”命令,再单击“是”按钮确认,系统对3-2.cpp进行编译。

步骤3:编译完成后,单击“Build”菜单中的“Build 3-2.exe”命令,建立3-2.exe可执行文件。

操作能否正常进行,如果不行,原因是什么? 解:程序能够正常执行。

步骤4:在工具栏单击“Execute program”按钮,执行3-2.exe程序。

请描述运行结果(如果运行不成功,则可能的原因是什么?):

解:程序主要是在互斥信号量的保证下限制两个线程之间对单一数值的访问。程序中用的信号量是m_nAccess,实现对m_nValue的递减。当信号量是1时实现第一个进程对数据的访问,这时候进程无法访问数据,在第一个进程访问结束之后,释放信号量,这样进程2就可以实现对数据的访问,而进程1则不能继续访问。依次循环,程序结果是:

thread:2068value:1access:50 thread:2320value:0access:49 thread:2068value:1access:48 thread:2320value:0access:47 thread:2068value:1access:46

thread:2320value:0access:45 thread:2068value:1access:44 thread:2320value:0access:43 thread:2068value:1access:42 thread:2320value:0access:41 thread:2068value:1access:40

…………….

thread:2320value:0access:1 thread:2068value:1access:0

3.5 实验总结

本次实验主要涉及的操作是线程的同步,例如互斥信号量容易创建、打开、使用并清除,并利用互斥信号量保证两个进程互斥的访问共享数据。

当一个任务想对临界区访问时,为了防止别的任务也对该临界区操作,它需要对该临界区上锁,这就是互斥信号量的作用。

1)利用CreateMutex()API函数可创建互斥信号量,使用OpenMutex()API函数来获得指向对象的句柄,放弃共享资源时需要在该对象上调用ReleaseMutex()。 2)学习了用于管理事件对象的API利用CreateEvent()函数创建事件,利用OpenEvent函数实现对已经创建对象的访问等。

3)在利用信号量实现两个进程之间互斥的访问数据的试验之中,用单步调试实时跟踪信号量和共享数据的状态。

4)在3-2程序中删除语句:: ReleaseMutex(m_hMutexValue);,即不对信号量进行释放,程序的运行结果就会变为:

这样就会变为只有进程1对共享的数据变量进行访问了, 程序2没有得到机会执行。

将构造函数中的ReleaseMutex(m_hMutexValue);注释之后,即运行到WaitForSingleObject会死锁。程序将不能访问变量了,程序将不会有任何的输出结果。

两个释放信号量的操作都存在的时候就能让两个进程交替的访问共享变量,程序将会输出正确的结果。

3.6 实验评价(教师)