教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 高等教育 >

天津科技大学操作系统实验1-5(4)

来源:网络收集 时间:2026-08-26
导读: 多次运行修改后的程序结果为: 【程序说明】多线程文件夹下 1-1.cpp文件:简单的多线程示例; 1-2.cpp文件:在1.cpp文件中加入循环,使得两个线程交替执行,理解时间片轮转调度,因为在两个线程中存在共享变量,因

多次运行修改后的程序结果为:

【程序说明】多线程文件夹下

1-1.cpp文件:简单的多线程示例;

1-2.cpp文件:在1.cpp文件中加入循环,使得两个线程交替执行,理解时间片轮转调度,因为在两个线程中存在共享变量,因此执行结果出现不可再现性。

1-3.cpp文件:编写一个模拟火车站售票系统的程序,多窗口售票可采用多线程技术实现。主线程创建两个线程(即两个售票窗口)。

7

实验二 Windows线程同步机制

【开发语言及实现平台或实验环境】

C++/C#

Microsoft Visual Studio 6.0/ Microsoft Visual Studio .NET

【实验目的】

(1) 了解Windows线程同步机制;

(2) 了解互斥体,并通过查阅资料理解互斥体对象的使用方法; (3) 了解事件,并通过查阅资料理解事件对象的使用方法; (4) 了解关键区,并通过查阅资料理解关键区对象的使用方法; (5) 了解信号量,并通过查阅资料理解信号量对象的使用方法; (6) 利用Windows线程同步机制,模拟生产者消费者问题。

【实验要求】

(1) 逐程序进行简要分析、运行各程序并仔细阅读注释;

(2) 查阅MSDN或其他资料,掌握相关系统调用使用方法和参数含义; (3) 完成实验报告。

【相关知识】

一、Windows线程同步机制

Windows 下提供了多种内核对象实现线程、进程间的同步和互斥,常用的有: 1、 关键区(临界区Critical Section)

关键区不是内核对象,在用户态实现了同一进程中线程的互斥。由于使用时不需要从用户态切换到核心态,所以速度很快( X86 系统上约为 20 个指令周期),但其缺点是不能跨进程同步,同时不能指定阻塞时的等待时间,只能无限等待。

使用关键区的方法则使同步管理的效率更高。使用时先定义一个CRITICAL SECTION结构的排斥区对象,在进程使用之前调用如下函数对对象进行初始化:

VOID InitializeCriticalSection(LPCRITICAL_SECTION);

当一个线程使用排斥区时,调用函数:EnterCriticalSection或者TryEnterCriticalSection; 当要求占用、退出排斥区时,调用函数LeaveCriticalSection,释放对排斥区对象的占用,供其他线程使用。 2、 互斥体( Mutex )

8

互斥体实现了和关键区类似的互斥功能,但区别在于:互斥体是内核对象,可以实现跨进程互斥,但需要在用户态和核心态之间切换,速度比关键区慢得多(X86 系统上约为 600 个指令周期),同时可以指定阻塞时的等待时间。

Mutex对象的状态在它不被任何线程拥有时才有信号,而当它被拥有时则无信号。Mutex对象很适合用来协调多个线程对共享资源的互斥访问。

可按下列步骤使用该对象:

首先,建立互斥体对象,得到句柄:HANDLE CreateMutex();

然后,在线程可能产生冲突的区域前(即访问共享资源之前)调用WaitForSingleObject,将句柄传给函数,请求占用互斥对象:

dwWaitResult=WaitForSingleObject(hMutex,5000L);

共享资源访问结束,释放对互斥体对象的占用:ReleaseMutex(hMutex);

互斥体对象在同一时刻只能被一个线程占用,当互斥体对象被一个线程占用时,若有另一线程想占用它,则必须等到前一线程释放后才能成功。 3、事件(Event)

事件也是内核对象,具有“信号态”和“无信号态”两种状态。当某一线程等待一个事件时,如果事件为信号态,将继续执行,如果事件为无信号态,那么线程被阻塞。线程能够指定阻塞时的等待时间。

例如:只有在通信端口缓冲区收到数据后,监视线程才被激活。事件对象是用CreateEvent函数建立的。该函数可以指定事件对象的类和事件的初始状态。如果是手工重置事件,那么它总是保持有信号状态,直到用ResetEvent函数重置成无信号的事件。如果是自动重置事件,那么它的状态在单个等待线程释放后会自动变为无信号的。用SetEvent可以把事件对象设置成有信号状态。在建立事件时,可以为对象命名,这样其他进程中的线程可以用OpenEvent函数打开指定名字的事件对象句柄。 4、信号量(Semaphore)

信号量是一个资源计数器,当某线程获取某信号量时,信号量计数首先减 1 ,如果计数小于 0 ,那么该线程被阻塞;当某县城释放某信号量时,信号量计数首先加 1 ,如果计数小于或等与 0,那么唤醒某被阻塞的线程并执行之。对信号量的总结如下:

? 如果计数器 m 大于 0 ,表示还有 m 个资源可以访问,此时信号量线程等待队列中没有线程

被阻塞,新的线程访问资源也不会被阻塞;

? 如果计数器 m 等与 0 ,表示没有资源可以访问,此时信号量线程等待队列中没有线程被阻

塞,但新的线程访问资源会被阻塞;

? 如果计数器 m 小于 0 ,表示没有资源可以访问,此时信号量线程等待队列中有 abs ( m )

个线程被阻塞,新的线程访问资源会被阻塞; 信号量常被用于保证对多个资源进行同步访问。

9

可按下列步骤使用该对象:

首先,创建信号对象:HANDLE CreateSemaphoreQ; 或者打开一个信号对象:HANDLE OpenSemaphoreQ; 然后,在线程访问共享资源之前调用:WaitForSingleObject;

共享资源访问完成后,应释放对信号对象的占用:ReleaseSemaphoreQ; 二、生产者-消费者模型 生产者-消费者模型是指:

? 生产者进行生产将物品放入仓库,同一时间只能有一个生产者将物品放入仓库,如果仓库

满,生产者等待。

? 消费者从仓库中取出物品,同一时间只能有一个消费者取出物品,如果仓库空,消费者等

待;

? 生产者将物品放入仓库时消费者不能同时取; ? 消费者取物品时生产者不能放入物品;

总之,就是生产者群体或消费者群体内部是互斥的,两个群体之间是同步的。

当只有一个生产者、消费者时,由于同一群体内部不需要互斥,所以只需在群体之间实 现同步即可。例如可以使用两个 Event/CriticalSection/Mutex/Semaphore 实现同步;

如果有多个生产者和消费者,那么情况会复杂些,需要一个 Event/CriticalSection/Mutex 实现线程之间的互斥,需要两个 Semaphore 实现两个线程群体间的同步。 【实验步骤】

(1) 阅读和理解2-1(mutex).cpp文件中的程序,运行2-1(mutex).cpp,认真观察结果。然后将两个子函数中注释掉的Sleep语句让其可用,再多次运行,认真观察结果,不会出现销售出0号票的情况。比较修改程序前后运行结果发生的变化,并分析其原因。

10

(2) 2-2(event).cpp、2-3(critical_section).cpp的处理方式同(1)。

2-2

2-3

分析:修改之前,在指定暂停的时间sleep(1000)内Sleep(1000);//要保证售完40张票之前线程不退出,thread1和thread2随机售票,出现多种情况;将两个子函数中注释掉的sleep(1)语句让其可用后,thread1和thread2交替售票,即thread1在其暂停的时间sleep(1)内,thread2获得了对共享对象hmutex的所有权,开始售票,同理当thread2在其暂停的时间sleep(1)内,thread1获得了对共享对象hmutex的所有权,开始售票,从而实现了交替售票。

11

…… 此处隐藏:1630字,全部文档内容请下载后查看。喜欢就下载吧 ……
天津科技大学操作系统实验1-5(4).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/614421.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)