文章分类 | 推荐文章 | 最新文章 | 热点文章 | 最新软件 | 精品软件 | 下载排行 | 推荐下载 | 免费看大片 | WPS | 杀毒软件
清风网络
首 页 软件下载 网络学院 数码学院
QQ 电脑入门 游戏 操作系统 图形处理 办公软件 媒体动画 精文荟萃 工具软件 网络编程 程序开发 网络技术 认证考试 网站建设 文章专栏
当前位置:清风网络学院程序开发C/C++Win32下两种用于C++的线程同步类(上)
精品推荐
特别推荐
·C语言编程易犯毛病集合
·C语言编程常见问题解答(目录)
·C#程序开发中的常用函数汇总
·C/C++笔试、面试题目大汇总
·Beej的网络socket编程指南
·socket编程原理
·C语言的常用库函数使用方法分析及用途
·在C语言中如何处理时间和日期
·C++设计模式之Singleton
·VC++动态链接库编程之MFC扩展 DLL
·TCP/IP网络重复型服务器通信软件的设计
·DirectX游戏开发入门
·经典与现代的结合:在MFC中集成RAD .NET框架
·Windows API-GDI入门基础知识详解(2)
·Visual C++ 入门精解
·C#基础概念二十五问
·用C#实现pdf文件的完整性验证
·成为嵌入式程序员应知道的0x10个问题
·TCP/IP编程实现远程文件传输
·几个C#编程的小技巧
热点TOP10
·学生成绩管理系统实习
·C#编写的windows计算器-源代码
·socket编程原理
·飞机订票系统设计
·C/C++笔试、面试题目大汇总
·TCP/IP编程实现远程文件传输
·Visual C++ 实现数字化图像的分割
·C语言图形函数
·改编 的 C版 职工管理系统
·C语言的常用库函数使用方法分析及用途
·C#基础概念二十五问
·C#源码读取excel数据到程序中-SQL SERVER-到dataset中
·用C语言实现Ping程序功能
·C# GridView 排序及分页
·进程调度模拟程序
·Windows下C语言网络编程快速入门
·通讯录的源代码(用链表实现)
·DirectX游戏开发入门
·在Visual Studio.NET中使用Crystal Report(上)
·asp.net中调用javascript函数实现多功能日期控件示例

Win32下两种用于C++的线程同步类(上)

日期:2007年8月16日 作者: 查看:[大字体 中字体 小字体]


线程同步是多线程程序设计的核心内容,它的目的是正确处理多线程并发时的各种问题,例如线程的等待、多个线程访问同一数据时的互斥,防死锁等。Win32提供多种内核对象和手段用于线程同步,如互斥量、信号量、事件、临界区等。所不同的是,互斥量、信号量、事件都是Windows的内核对象,当程序对这些对象进行控制时会自动转换到核心态,而临界区本身不是内核对象,它是工作在用户态的。我们知道从用户态转换到核心态是需要以时间为代价的,所以如果能在用户态就简单解决的问题,就可以不必劳烦核心态了。

  这里我要说的是两种用于C++的多线程同步类,通过对这两种类的使用就可以方便的实现对变量或代码段的加锁控制,从而防止多线程对变量不正确的操作。

  所谓加锁,就是说当我们要访问某关键变量之前,都需要首先获得允许才能继续,如果未获得允许则只有等待。一个关键变量拥有一把锁,一个线程必须先得到这把锁(其实称为钥匙可能更形象)才可以访问这个变量,而当某个变量持有这把锁的时候,其他线程就不能重复的得到它,只有等持有锁的线程把锁归还以后其他线程才有可能得到它。之所以这样做,就是为了防止一个线程读取某对象途中另一线程对它进行了修改,或两线程同时对一变量进行修改,例如:

// 全局:
struct MyStruct ... { int a, b; } ;
MyStruct s;
// 线程1:
int a = s.a;
int b = s.b;
// 线程2:
s.a ++ ;
s.b -- ;
  如果实际的执行顺序就是上述书写的顺序那到没有什么,但如果线程2的执行打断了线程1,变为如下顺序:

int a = s.a; //线程1
s.a++; //线程2
s.b++; //线程2
int b = s.b; //线程1
  那么这时线程1读出来的a和b就会有问题了,因为a是在修改前读的,而b是在修改后读的,这样读出来的是不完整的数据,会对程序带来不可预料的后果。天知道两个程的调度顺序是什么样的。为了防止这种情况的出现,需要对变量s加锁,也就是当线程1得到锁以后就可以放心的访问s,这时如果线程2要修改s,只有等线程1访问完成以后将锁释放才可以,从而保证了上述两线程交叉访问变量的情况不会出现。

  使用Win32提供的临界区可以方便的实现这种锁:

// 全局:
CRITICAL_SECTION cs;
InitializeCriticalSection( & cs);
// 线程1:
EnterCriticalSection( & cs);
int a = s.a;
int b = s.b;
LeaveCriticalSection( & cs);
// 线程2:
EnterCriticalSection( & cs);
s.a ++ ;
s.b -- ;
LeaveCriticalSection( & cs);
// 最后:
DeleteCriticalSection( & cs);
  代码中的临界区变量(cs)就可以看作是变量s的锁,当函数EnterCriticalSection返回时,当前线程就获得了这把锁,之后就是对变量的访问了。访问完成后,调用LeaveCriticalSection表示释放这把锁,允许其他线程继续使用它。

  如果每当需要对一个变量进行加锁时都需要做这些操作,显得有些麻烦,而且变量cs与s只有逻辑上的锁关系,在语法上没有什么联系,这对于锁的管理带来了不小的麻烦。程序员总是最懒的,可以想出各种偷懒的办法来解决问题,例如让被锁的变量与加锁的变量形成物理上的联系,使得锁变量成为被锁变量不可分割的一部分,这听起来是个好主意。

  首先想到的是把锁封闭在一个类里,让类的构造函数和析构函数来管理对锁的初始化和锁毁动作,我们称这个锁为“实例锁”:

class InstanceLockBase
... {
CRITICAL_SECTION cs;
protected :
InstanceLockBase() ... { InitialCriticalSection( & cs); }
~ InstanceLockBase() ... { DeleteCriticalSection( & cs); }
} ;
  如果熟悉C++,看到这里一定知道后面我要干什么了,对了,就是继承,因为我把构造函数和析构函数都声明为保护的(protected),这样唯一的作用就是在子类里使用它。让我们的被保护数据从这个类继承,那么它们不就不可分割了吗:

struct MyStruct: public InstanceLockBase
... { … } ;
  什么?结构体还能从类继承?当然,C++中结构体和类除了成员的默认访问控制不同外没有什么不一样,class能做的struct也能做。此外,也许你还会问,如果被锁的是个简单类型,不能继承怎么办,那么要么用一个类对这个简单类型进行封装(记得Java里有int和Integer吗),要么只好手工管理它们的联系了。如果被锁类已经有了基类呢?没关系,C++是允许多继承的,多一个基类也没什么。

  现在我们的数据里面已经包含一把锁了,之后就是要添加加锁和解锁的动作,把它们作为InstanceLockBase类的成员函数再合适不过了:

class InstanceLockBase
... {
 CRITICAL_SECTION cs;

[1] [2] [3] 下一页 




上一篇:显示消息框的程序

下一篇:C++启蒙教程之教你编写简单的C++程序

Win32下两种用于C++的线程同步类(上) 相关文章:
·QQ好友隐身也难 两种方法抓出隐身好友
·Exce表格分栏打印输出的两种巧妙方法
·进程和线程编程
·菲议存储:实现 iSCSI Initiator 的两种方法
·两种木马手工清除
·SQLSERVER中,数据库同步的实现
·Windows多线程间同步事件的控制方法
·解除 WINDOWS XP SP2 10线程连接限制
·浅析DirectShow音视频同步解决完整方案
·VC中利用多线程技术实现线程之间的通信
Win32下两种用于C++的线程同步类(上) 相关软件:
·多线程ping服务系统V1.2
·适用于 Windows XP/2003 的“Windows 边栏”
·windows vista外壳 rar 适用于sp2
·动感在线程序更新器 v1.0
·卧天同步王V1.84
·与孙子兵法同步思考
·魔幻霸主(Armies of Exigo)免CD补丁及编辑器免CD补丁(本补丁只提供给正版用户作保护光盘使用,请勿用于其他用途)
·Fast Browser Pro优秀多线程浏览器V8.1
·风色幻想3繁体中文版 完美破解免CD补丁(目前通用于繁体中文版本的原版和所有升级档
·我国粮食市场上的同步性问题分析

特别声明:本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
[打印本页] [关闭窗口] 转载请注明来源:http://www.vipcn.com
| 帮助(?) | 版权声明 | 友情连接 | 关于我们 | 信息发布
Copyright 2007 www.vipcn.com All Rights Reserved. 鄂ICP备05000083号Powered by:vipcn