没有合适的资源?快使用搜索试试~ 我知道了~
首页Visual C++线程同步技术剖析
Visual C++线程同步技术剖析
需积分: 3 20 下载量 143 浏览量
更新于2023-03-16
评论
收藏 117KB DOC 举报
多线程同步技术是计算机软件开发的重要技术,本文对多线程的各种同步技术的原理和实现进行了初步探讨。 讲解了windows内核编程中个中同步方法的原理,并有代码示例 吐血推荐
资源详情
资源评论
资源推荐
Visual C++线程同步技术剖析
摘要: 多线程同步技术是计算机软件开发的重要技术,本文对多线程的各种同步技术的原
理和实现进行了初步探讨。
关键词: VC++6.0; 线程同步;临界区;事件;互斥;信号量;
正文
使线程同步
在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作。
更多的情况是一些线程进行某些处理操作,而其他的线程必须对其处理结果进行了解。正
常情况下对这种处理结果的了解应当在其处理任务完成后进行。
如果不采取适当的措施,其他线程往往会在线程处理任务结束前就去访问处理结果,
这就很有可能得到有关处理结果的错误了解。例如,多个线程同时访问同一个全局变量,
如果都是读取操作,则不会出现问题。如果一个线程负责改变此变量的值,而其他线程负
责同时读取变量内容,则不能保证读取到的数据是经过写线程修改后的。
为了确保读线程读取到的是经过修改的变量,就必须在向变量写入数据时禁止其他线
程对其的任何访问,直至赋值过程结束后再解除对其他线程的访问限制。象这种保证线程
能了解其他线程任务处理结束后的处理结果而采取的保护措施即为线程同步。
线程同步是一个非常大的话题,包括方方面面的内容。从大的方面讲,线程的同步可
分用户模式的线程同步和内核对象的线程同步两大类。用户模式中线程的同步方法主要有
原子访问和临界区等方法。其特点是同步速度特别快,适合于对线程运行速度有严格要求
的场合。
内核对象的线程同步则主要由事件、等待定时器、信号量以及信号灯等内核对象构成
由于这种同步机制使用了内核对象,使用时必须将线程从用户模式切换到内核模式,而这
种转换一般要耗费近千个 CPU 周期,因此同步速度较慢,但在适用性上却要远优于用户模
式的线程同步方式。
临界区
临界区(Critical Section)是一段独占对某些共享资源访问的代码,在任意时刻只
允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个
线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程
离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源
的目的。
临界区在使用时以 CRITICAL_SECTION 结构对象保护共享资源,并分别用
EnterCriticalSection()和 LeaveCriticalSection()函数去标识和释放一个临界区。
所用到的 CRITICAL_SECTION 结构对象必须经过 InitializeCriticalSection()的初始化
后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区
的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。
图 1 使用临界区保持线程同步
下面通过一段代码展示了临界区在保护多线程访问的共享资源中的作用。通过两个线
程来分别对全局变量 g_cArray[10]进行写入操作,用临界区结构对象 g_cs 来保持线程的
同步,并在开启线程前对其进行初始化。为了使实验效果更加明显,体现出临界区的作用,
在线程函数对共享资源 g_cArray[10]的写入时,以 Sleep()函数延迟 1 毫秒,使其他
线程同其抢占 CPU 的可能性增大。如果不使用临界区对其进行保护,则共享资源数据将被
破坏(参见图 1(a)所示计算结果),而使用临界区对线程保持同步后则可以得到正确的
结果(参见图 1(b)所示计算结果)。代码实现清单附下:
// 临界区结构对象
CRITICAL_SECTION g_cs;
// 共享资源
char g_cArray[10];
UINT ThreadProc10(LPVOID pParam)
{
// 进入临界区
EnterCriticalSection(&g_cs);
// 对共享资源进行写入操作
for (int i = 0; i < 10; i++)
{
g_cArray[i] = 'a';
Sleep(1);
}
// 离开临界区
LeaveCriticalSection(&g_cs);
return 0;
}
UINT ThreadProc11(LPVOID pParam)
{
// 进入临界区
EnterCriticalSection(&g_cs);
// 对共享资源进行写入操作
for (int i = 0; i < 10; i++)
{
g_cArray[10 - i - 1] = 'b';
Sleep(1);
}
// 离开临界区
LeaveCriticalSection(&g_cs);
return 0;
}
……
void CSample08View::OnCriticalSection()
{
// 初始化临界区
InitializeCriticalSection(&g_cs);
// 启动线程
AfxBeginThread(ThreadProc10, NULL);
AfxBeginThread(ThreadProc11, NULL);
// 等待计算完毕
Sleep(300);
// 报告计算结果
CString sResult = CString(g_cArray);
AfxMessageBox(sResult);
}
在使用临界区时,一般不允许其运行时间过长,只要进入临界区的线程还没有离开,
其他所有试图进入此临界区的线程都会被挂起而进入到等待状态,并会在一定程度上影响。
程序的运行性能。尤其需要注意的是不要将等待用户输入或是其他一些外界干预的操作包
含到临界区。如果进入了临界区却一直没有释放,同样也会引起其他线程的长时间等待。
换句话说,在执行了 EnterCriticalSection()语句进入临界区后无论发生什么,必须确保
与之匹配的 LeaveCriticalSection()都能够被执行到。可以通过添加结构化异常处理代码
来确保 LeaveCriticalSection()语句的执行。虽然临界区同步速度很快,但却只能用来同
步本进程内的线程,而不可用来同步多个进程中的线程。
MFC 为临界区提供有一个 CCriticalSection 类,使用该类进行线程同步处理是非常简单
的,只需在线程函数中用 CCriticalSection 类成员函数 Lock()和 UnLock()标定出被保
护代码片段即可。对于上述代码,可通过 CCriticalSection 类将其改写如下:
// MFC 临界区类对象
CCriticalSection g_clsCriticalSection;
// 共享资源
char g_cArray[10];
UINT ThreadProc20(LPVOID pParam)
{
// 进入临界区
g_clsCriticalSection.Lock();
// 对共享资源进行写入操作
for (int i = 0; i < 10; i++)
{
g_cArray[i] = 'a';
Sleep(1);
}
// 离开临界区
g_clsCriticalSection.Unlock();
return 0;
}
UINT ThreadProc21(LPVOID pParam)
{
// 进入临界区
g_clsCriticalSection.Lock();
// 对共享资源进行写入操作
for (int i = 0; i < 10; i++)
{
g_cArray[10 - i - 1] = 'b';
Sleep(1);
}
// 离开临界区
g_clsCriticalSection.Unlock();
return 0;
}
……
void CSample08View::OnCriticalSectionMfc()
{
// 启动线程
AfxBeginThread(ThreadProc20, NULL);
AfxBeginThread(ThreadProc21, NULL);
// 等待计算完毕
Sleep(300);
// 报告计算结果
CString sResult = CString(g_cArray);
AfxMessageBox(sResult);
}
管理事件内核对象
在前面讲述线程通信时曾使用过事件内核对象来进行线程间的通信,除此之外,事件
内核对象也可以通过通知操作的方式来保持线程的同步。对于前面那段使用临界区保持线
程同步的代码可用事件对象的线程同步方法改写如下:
剩余17页未读,继续阅读
塞翁失马焉知非福8
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- stc12c5a60s2 例程
- Android通过全局变量传递数据
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0