没有合适的资源?快使用搜索试试~ 我知道了~
Windows的多线程同步实验报告.doc
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 55 浏览量
2022-07-07
02:07:55
上传
评论
收藏 304KB DOC 举报
温馨提示
试读
22页
Windows的多线程同步实验报告
资源推荐
资源详情
资源评论
一、实验目的
在掌握基于消息的 windows 程序结构和多线程程序设计方法的基础上,设
计一个多线程同步的程序。使学生能够从程序设计的角度了解多线程程序设计
的方法和在 windows 系统下多线程同步互斥的机制。
二、实验内容
1.理解 Windows 程序设计的基本思想,理解基于消息的程序设计方法,能
够设计出简单的基于事件的 windows 程序,完成基本控件的使用
2.结合操作系统中信号量与互斥体的概念,在 MFC 中找到对应的相关类
3.设计一个多线程同步的程序,
多线程概述
进程和线程都是操作系统的概念。进程是应用程序的执行实例,每个进程是
由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程
中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放
或关闭。
线程是进程内部的一个执行单元。系统创建好进程后,实际上就启动执行了
该进程的主执行线程,主执行线程以函数地址形式,比如说 main 或 WinMain 函
数,将程序的启动点提供给 Windows 系统。主执行线程终止了,进程也就随之终
止。
每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自
动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同
一个进程中。一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这
些虚拟地址空间、全局变量和系统资源,所以线程间的通讯非常方便,多线程技
术的应用也较为广泛。
多线程可以实现并行处理,避免了某项任务长时间占用 CPU 时间。要说明的
一点是,目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,
操作系统为每个独立线程安排一些 CPU 时间,操作系统以轮换方式向线程提供时
间片,这就给人一种假象,好象这些线程都在同时运行。由此可见,如果两个非
常活跃的线程为了抢夺对 CPU 的控制权,在线程切换时会消耗很多的 CPU 资源,
反而会降低系统的性能。这一点在多线程编程时应该注意。
Win32 SDK 函数支持进行多线程的程序设计,并提供了操作系统原理中的各
种同步、互斥和临界区等操作。Visual C++ 6.0 中,使用 MFC 类库也实现了多线
程的程序设计,使得多线程编程更加方便。
VC 中提供线程同步的方法:
临界区(CCriticalSection)
事件(CEvent)
互斥量(CMutex)
信号量(CSemaphore)
A、使用 CCriticalSection 类
当多个线程访问一个独占性共享资源时,可以使用“临界区”对象。任一时
刻只有一个线程可以拥有临界区对象,拥有临界区的线程可以访问被保护起来的
资源或代码段,其他希望进入临界区的线程将被挂起等待,直到拥有临界区的线
程放弃临界区时为止,这样就保证了不会在同一时刻出现多个线程访问共享资源。
CCriticalSection 类的用法非常简单,步骤如下:
定义 CCriticalSection 类的一个全局对象(以使各个线程均能访问),如
CCriticalSection critical_section;
在访问需要保护的资源或代码之前,调用 CCriticalSection 类的成员 Lock()
获得临界区对象: critical_section.Lock();
在线程中调用该函数来使线程获得它所请求的临界区。如果此时没有其它线
程占有临界区对象,则调用 Lock()的线程获得临界区;否则,线程将被挂起,并
放入到一个系统队列中等待,直到当前拥有临界区的线程释放了临界区时为止。
访问临界区完毕后,使用 CCriticalSection 的成员函数 Unlock()来释放临界区:
critical_section.Unlock();
再通俗一点讲,就是线程 A 执行到 critical_section.Lock();语句时,如果其它
线程(B)正在执行 critical_section.Lock();语句后且 critical_section. Unlock();语句
前的语句时,线程 A 就会等待,直到线程 B 执行完 critical_section. Unlock();语
句,线程 A 才会继续执行。
B、使用 CEvent 类
CEvent 类提供了对事件的支持。事件是一个允许一个线程在某种情况发生
时,唤醒另外一个线程的同步对象。例如在某些网络应用程序中,一个线程(记
为 A)负责监听通讯端口,另外一个线程(记为 B)负责更新用户数据。通过使
用 CEvent 类,线程 A 可以通知线程 B 何时更新用户数据。每一个 CEvent 对象
可以有两种状态:有信号状态和无信号状态。线程监视位于其中的 CEvent 类对
象的状态,并在相应的时候采取相应的操作。
在 MFC 中,CEvent 类对象有两种类型:人工事件和自动事件。一个自动
CEvent 对象在被至少一个线程释放后会自动返回到无信号状态;而人工事件对
象获得信号后,释放可利用线程,但直到调用成员函数 ReSetEvent()才将其设置
为无信号状态。在创建 CEvent 类的对象时,默认创建的是自动事件。 CEvent
类的各成员函数的原型和参数说明如下:
1、CEvent(BOOL bInitiallyOwn=FALSE,
BOOL bManualReset=FALSE,
LPCTSTR lpszName=NULL,
LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);
bInitiallyOwn:指定事件对象初始化状态,TRUE 为有信号,FALSE 为无信号;
bManualReset:指定要创建的事件是属于人工事件还是自动事件。TRUE 为人工
事件,FALSE 为自动事件;
后两个参数一般设为 NULL,在此不作过多说明。
2、BOOL CEvent::SetEvent();
将 CEvent 类对象的状态设置为有信号状态。如果事件是人工事件,则
CEvent 类对象保持为有信号状态,直到调用成员函数 ResetEvent()将 其重新设
为无信号状态时为止。如果 CEvent 类对象为自动事件,则在 SetEvent()将事件
设置为有信号状态后,CEvent 类对象由系统自动重置为无信号状态。
如果该函数执行成功,则返回非零值,否则返回零。 3、BOOL CEvent::
ResetEvent();
该函数将事件的状态设置为无信号状态,并保持该状态直至 SetEvent()被调
用时为止。由于自动事件是由系统自动重置,故自动事件不需要调用该函数。如
果该函数执行成功,返回非零值,否则返回零。我们一般通过调用
WaitForSingleObject 函数来监视事件状态。前面我们已经介绍了该函数。由于语
言描述的原因,CEvent 类的理解确实有些难度,但您只要通过仔细玩味下面例
程,多看几遍就可理解。
C、使用 CMutex 类
互斥对象与临界区对象很像.互斥对象与临界区对象的不同在于:互斥对象可
以在进程间使用,而临界区对象只能在同一进程的各线程间使用。当然,互斥对
象也可以用于同一进程的各个线程间,但是在这种情况下,使用临界区会更节省
系统资源,更有效率。
D、使用 CSemaphore 类
当需要一个计数器来限制可以使用某个线程的数目时,可以使用“信号量”
对象。CSemaphore 类的对象保存了对当前访问某一指定资源的线程的计数值,
该计数值是当前还可以使用该资源的线程的数目。如果这个计数达到了零,则所
有对这个 CSemaphore 类对象所控制的资源的访问尝试都被放入到一个队列中
等待,直到超时或计数值不为零时为止。一个线程被释放已访问了被保护的资源
时,计数值减 1;一个线程完成了对被控共享资源的访问时,计数值增 1。这个
被 CSemaphore 类对象所控制的资源可以同时接受访问的最大线程数在该对象
的构建函数中指定。
CSemaphore 类的构造函数原型及参数说明如下:
CSemaphore (LONG lInitialCount=1,
LONG lMaxCount=1,
LPCTSTR pstrName=NULL,
LPSECURITY_ATTRIBUTES lpsaAttributes=NULL);
lInitialCount:信号量对象的初始计数值,即可访问线程数目的初始值;
lMaxCount:信号量对象计数值的最大值,该参数决定了同一时刻可访问由
信号量保护的资源的线程最大数目;
后两个参数在同一进程中使用一般为 NULL,不作过多讨论;
在用 CSemaphore 类的构造函数创建信号量对象时要同时指出允许的最大
资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,
每增加一个线程对共享资源的访问,当前可用资源计数就会减 1,只要当前可用
资源计数是大于 0 的,就可以发出信号量信号。但是当前可用计数减小到 0 时,
则说明当前占用资源的线程数已经达到了所允许的最大数目,不能再允许其它线
程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开
的同时通过 ReleaseSemaphore()函数将当前可用资源数加 1。
三、实验方案
本系统通过VC提供的四种线程同步方案同时实现线程的同步。其架构图如
图 1-1 所示。
多线程同步
通过事件同步
通过互斥锁同步
通过同步与不同步
两种情况写AB
通过复
制文件
来体现
同步
通过信号量同步
通过临界资源同步
图 1-1 系统结构示意图
通过 VC 提供的线程创建函数:
CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc,
LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT
nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES
lpSecurityAttrs = NULL );
CWinThread* AfxBeginThread( CRuntimeClass*
pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0, DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
创建多线程,分别通过临界区(CCriticalSection)、事件(CEvent)、互斥量
(CMutex)、信号量(CSemaphore)实现同步。
四、实验(设计)仪器设备和材料清单
PC 每人一台,windows2000 操作系统,Vc++ 6.0,msdn
五、调试及结果测试
在本实验中由于实验简单很容易就调试通过。
1.本系统采用MFC编程。其运行界面如图 1-2 所示。分别人事件、互斥
量、临界资源、信号量实现线程同步。
图 1-2 系统运行界面
2.单击 SYNCH(同步按钮)会出现先写完A后再写B。如果单击 ASYNCH
按钮(异步按钮)则会出现AB交错出现这种现象这正在非同步所出现的现象。
如图 1-3 所示。
剩余21页未读,继续阅读
资源评论
oligaga
- 粉丝: 50
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Flume进阶-自定义拦截器jar包
- Dubins曲线算法讲解和在运动规划中的使用.pdf
- 上市公司-股票性质数据-工具变量(民企、国企、央企)2003-2022年.dta
- 上市公司-股票性质数据-工具变量(民企、国企、央企)2003-2022年.xlsx
- Reeds+Shepp曲线算法讲解和实现.pdf
- 毕业设计基于SpringBoot+MyBatisPlus+MySQL+Vue的外卖配送信息系统源代码+数据库
- 词向量(Word Embeddings)是自然语言处理(NLP)领域的一种重要技术.txt
- Surfer,线性函数
- MyBatis 的动态 SQL 是其核心特性之一.txt
- 时代的sdddsddsddsd
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功