2024年3月28日发(作者:)

实验二 并发与调度

一、实验目的

在本实验中,通过对事件和互斥体对象的了解,来加深对Windows 2000线程同步的理

解。通过分析实验程序,了解管理事件对象的API。了解在进程中如何使用事件对象,在进

程中如何使用互斥体对象,线程如何通过文件映射对象发送数据。

二、实验环境

硬件环境:计算机一台,局域网环境;

软件环境:Windows 2000 Professional,Visual C++ 6.0专业版或企业版。

三、实验内容和步骤

第一部分:互斥体对象

本程序中显示的类CCountUpDown使用了一个互斥体来保证对两个线程间单一数值的

访问。每个线程都企图获得控制权来改变该数值,然后将该数值写入输出流中。创建者实际

上创建的是互斥体对象,计数方法执行等待并释放,为的是共同使用互斥体所需的资源 (因

而也就是共享资源) 。

1、利用互斥体保护共享资源

程序参见实验指导书

分析程序的运行结果,

可以看到线程 (加和减线程) 的交替执行 (因为Sleep() API允许Windows切换线程) 。

在每次运行之后,数值应该返回初始值 (0) ,因为在每次运行之后写入线程在等待队列中

变成最后一个,内核保证它在其他线程工作时不会再运行。

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

2) 根据运行输出结果,对照分析程序,可以看出程序运行的流程吗?请简单描述:

_____逆向运行__________

第二部分线程通过文件对象发送数据

Windows 2000提供的线程间通讯类内核对象允许同一进程或跨进程的线程之间互相发

送信息,包括文件、文件映射、邮件位和命名管道等,其中最常用的是文件和文件映射。这

类对象允许一个线程很容易地向同一进程或其他进程中的另一线程发送信息。

1、演示线程通过文件对象发送数据

程序参见实验指导书

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

阅读和分析程序,请回答问题:

1) 程序中启动了多少个单独的读写线程?

__________100__________________________________________________________

2) 使用了哪个系统API函数来创建线程例程?

_________

CreateThread()

________________________________

3) 文件的读和写操作分别使用了哪个API函数?

_______

ReadFile()

______

WriteFile

()_____________

每次运行进程时,都可看到程序中的每个线程从前面的线程中读取数据并将数据增加,

文件中的数值连续增加。这个示例是很简单的通讯机制。可将这一示例用作编写自己的文件

读/写代码的模板。

请注意程序中写入之前文件指针的重置。重置文件指针是必要的,因为该指针在读取结

束时将处于前四个字节之后,同一指针还要用于向文件写入数据。如果函数向该处写入新数

值,则下次进程运行时,只能读到原来的数值。那么:

4) 在程序中,重置文件指针使用了哪一个函数?

___________

hThread

__________________

5) 从输出结果,对照分析程序,可以看出程序运行的流程吗?请简单描述:

______........41,42,43,44,45,46,47……. ____________

2、演示使用映射文件的内存交换数据的线程

程序参见实验指导书

阅读和分析程序,请回答:

1) 程序中用来创建一个文件映射对象的系统API函数是哪个?

______

CreateFileMapping

()______________________

2) 在文件映射上创建和关闭文件视图分别使用了哪一个系统函数?

a. __

MapViewOfFile

()____

b. __

UnmapViewOfFile()

_

3) 运行时,程序首先通过 (

CreateFileMapping

() ) 函数创建一个小型的文件映射对象

( null ) ,接着,使用系统API函数 (

CreateMutex

) 再创建一个保护其应用

的互斥体 ( NULL ) 。然后,应用程序创建100个线程,每个都允许进行

同样的进程,即:通过互斥体获得访问权,这个操作是由语句:_

CreateThread()

________________

实现的。再通过函数 (

MapViewOfFile

() ) 操作将视图映射到文件,将高32位看作

有符号整数,将该数值增加 (即命令:_

f (pData != NULL)

{

:: ZeroMemory(pData, sizeof(LONG) ) ;

}

) ,再将新数值显示在控制台上。每个线程清除文件的视图并在退出之前

释放互斥体释放互斥体的语句是____

:: CloseHandle(hThread)

______________。当线程完成时,

应用程序关闭并退出。

4) 将程序中的语句 :: Sleep(500) ; 删除 (例如在语句前面加上“//”) 后,重新编译运

行,结果有变化吗?为什么?

四、实验总结

请总结一下本次实验的收获、教训和感受,结合课本内容谈一下你对进程间控制的理解。

现代操作系统是并发活动的管理机构,其本身也是并发执行的。进程能充分体现系统的

并发特征。因此,创建进程、撤消进程、实现进程状态变迁都是操作系统的底层功能之一,

称为进程控制。进程控制程序本身属于操作系统的内核。

对传统的内核模块进行分析后发现能剥离与硬件无关的代码,使操作系统最基本的功能

放在一个小核心中,其他功能尽量放到核外、通过调用小核心来实现,这就是当今流行的微

核技术。这样的小核心称为微核(micro kernel) 或微内核,它仅提供四类小型服务:

(1)进程间通信(IPC,InterProcess Communication);

(2)底层输入输出;

(3)有限调度和有限进程控制;

(4)最低级的存储管理。

微核的代码量大体控制在10KB~100KB之间。微核是对传统内核涵义的回归与进一步

提炼,它有4种优点:

(1)简化了代码的维护工作。

大的内核,其内部关系相互牵连,局部代码变动会影响其它表面上看来无关部分的操作。

所以,如果试图确定错误或扩大功能,设计人员必须十分仔细且要反复测试。相比之下,微

核代码量少,容易维护。

(2)系统崩溃的风险很小。

当增加操作系统功能时,只在微核外调试和运行(它们和用户应用程序处于同等地位),

即使出乱,也不会危及微核,整个系统的安全系数较高。

(3)方便于移植。

由于新的计算机芯片不断涌现,操作系统的移植一直困扰人们。微核中与硬件相关的代

码已分离出来,只要修改这部分代码就能适应不同硬件平台。修改工作可以通过类似于交叉

汇编的工具自动完成。

(4)灵活性。

基于微核可以开发多种类型的操作系统,以满足用户的嗜好。例如在微核上 提供一组

UNIX服务程序,系统对于用户好象是UNIX机器。如果提供一组Windows服务程序,系统

对于用户好象是Windows机器。

微核技术正成为一种潮流,Windows NT采用的是Microsoft的微核。IBM微核技术是

基于美国Carnegie Mellon大学开发的Mach。Mach将成为新版OS/2操作系统、新版UNIX

操作系统的基础。

内核或微核提供核外调用的过程或函数称为原语(primitive)。原语是一段用机器指令编

写的完成特定功能的程序,在执行过程中不允许中断。原语和系统调用(system call)在调用

的语法形式上相同,但系统调用在执行期间允许中断而原语不行。系统调用的实现过程可能

使用了原语,但原语的实现绝不会使用系统调用。

下面列举常用的进程控制原语:

(1)创建原语create

输入参数:进程名,优先数,构成PCB的其他必需参数

返回参数:进程号

功能:构造PCB,使该PCB列入就绪队列。谁使用create原语,谁就是新进程的父

进程。

(2)撤消原语kill

输入参数:进程号

返回:成功或失败标记

功能:撤销指定进程的PCB收回该进程拥有的全部资源

(3)唤醒原语wakeup

输入参数:进程号

返回:成功或失败标记

功能:把指定进程的PCB从阻塞队列摘下,改状态为“就绪”后,列入就绪队列。

(4)阻塞原语block

输入参数:无

返回:转进程调度

功能:把现行进程的PCB置成“阻塞”状态后列入阻塞队列。