当多个线程同时使用相同的资源时,由于是并发执行,不能保证先后顺序.所以假如时一个公共变量被几个线程同时使用会造成该变量值的混乱.

下面来举个简单例子.

假如有一个字符数组变量

char g_charArray[4];

CString szResult;

AfxBeginThread(FunOne,NULL);  //FunOne给数组赋值全为S

AfxBeginThread(FunTwo,NULL); //FunTwo也给数组赋值全为B

AfxBeginThread(GetResult,NULL);   //得到数组的值,本来期望的值为最后一次赋的值BBBB.但实际结果是不确定的,可能是SBSB,SSBB或者其它

UINT FunOne(LPVOID pParam){ //给数组赋值

for(int i =0; i < 4; i++){

g_charArray[i] = 'S';

Sleep(10);

}

return 0;

}

UINT FunTwo(LPVOID pParam){//得到数组值

for(int i =0; i < 4; i++){

g_charArray[i] = 'B';

Sleep(10);

}

return 0;

}

UINT GetResult(LPVOID pParam){//给数组赋值

szResult = CString(g_charArray);

return 0;

}

Win32 API中临界区(Critical Section)

为了使公共变量不会被毫无秩序,混乱的更改.我们希望一个线程使用这个变量时其他线程就不能使用,只能等别的线程用完了才用.

于是出现了临界区这说法,相当于把使用到的变量的内存看作一块区域,当某个线程使用时就进入该区域,使用完了离开.当有一个线程进入该区域时其他线程就只能在外面等.临界区的使用如下.

临界区只能用于同一个进程内的线程同步.如果想要多个进程间的线程同步就不能用它了.

CRITICAL_SECTION g_criSection //定义临界区变量

void MainTestFun{

InitializeCriticalSection(&g_criSection);  //使用前必须初始化

char g_charArray[4];

CString szResult;

AfxBeginThread(FunOne,NULL);

AfxBeginThread(FunTwo,NULL);

AfxBeginThread(GetResult,);  //此时得到的值总是BBBB或者SSSS,哪一个线程拥有临界区不确定.只能保证某一个时间只能有一个线程拥有

//DeleteCriticalSection(&g_criSection); 使用完了临界区就要删除掉,但是在这里这样使用可能会出错.因为必须保证在删除时这个临界区没有再被使用了.所以如果一个类中,一般把它放析构函数中去调用.

}

//在线程调用的函数的开始调用EnterCriticalSection结束时调用CriticalSection(&g_criSection);

//在中间有用到的所有资源在被使用时其他线程不能使用(不能读也不能改写).其它两个函数FunOne,GetResult按同样的方法添加这两行代码.这里不再写出来了.

UINT FunOne(LPVOID pParam){

EnterCriticalSection(&g_criSection); //表示进入临界区

for(int i =0; i < 4; i++){

g_charArray[i] = 'S';

Sleep(1);

}

LeaveCriticalSection(&g_criSection); //离开临界区

return 0;

}

MFC中的临界区类

MFC把上面的操作封装成一个类CCriticalSection,使用函数Lock与Unlock表示进入和离开临界区.上锁和解锁的说法是更符合我们的习惯思维的.

#include "afxmt.h" //需要添加该头文件引用

CCriticalSection g_criSection;

void MainTestFun{

char g_charArray[4];

CString szResult;

AfxBeginThread(FunOne,NULL);

AfxBeginThread(FunTwo,NULL);

AfxBeginThread(GetResult,); //此时得到的值总是BBBB或者SSSS,哪一个线程拥有临界区不确定.只能保证某一个时间只能有一个线程拥有 }

//其它两个类也同样加上这两行代码

UINT FunOne(LPVOID pParam){

g_criSection.Lock()//给所有使用的资源上锁

for(int i =0; i < 4; i++){

g_charArray[i] = 'S';

Sleep(1);

}

g_criSection.UnLock(); //给使用的资源解锁

return 0;

}

其他线程同步的方法

使线程同步共有4种方法:

1.临界区(critical section)

2.事件(event)

3.信号量(Semaphore)

4.互拆量(Mutex)

其中1临界区是用户对象,所以没太多权限,只能处理同一个进程内的线程同步

而剩下的2,3,4都是内核对象,权限比较大,可以跨进程使用,因此能够处理不同进程间的线程同步问题.

其中的Mutext和临界区适用的场景基本上一样,只不过Mutext是内核对象,而critical section是用户对象

MFC线程(二):线程同步临界区CRITICAL SECTION的更多相关文章

  1. C#中的线程(二) 线程同步基础

    1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...

  2. 第二十篇 .NET高级技术之C#中的线程(二) 线程同步基础

    1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...

  3. 临界区(Critical Section)的封装和使用示例

    向我老大致敬! 这个做法其实是抄我老大的.服务器中,多线程经常需要使用临界区,为了简化代码的使用,把临界区封装为 CThreadLockHandle  类,通过封装,使用临界区资源每次只需要一行代码, ...

  4. win32多线程 (二)线程同步之临界区 (critical sections)

    所谓critical sections 意指一小块“用来处理一份被共享之资源”的程序代码.你可能必须在程序的许多地方处理这一块可共享的资源.所有这些程序代码可以被同一个critical  sectio ...

  5. MFC 多线程及线程同步

    一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常 ...

  6. java线程 同步临界区:thinking in java4 21.3.5

    java线程 同步临界区:thinking in java4 21.3.5 thinking in java 4免费下载:http://download.csdn.net/detail/liangru ...

  7. MFC线程(三):线程同步事件(event)与互斥(mutex)

    前面讲了临界区可以用来达到线程同步.而事件(event)与互斥(mutex)也同样可以做到. Win32 API中的线程事件 HANDLE hEvent = NULL; void MainTestFu ...

  8. MFC【17-2】线程和线程同步化

    17-2线程同步 Windows支持4中类型的同步对象,可以用过来同步由并发运行的线程执行的操作: 临界区 互斥量 事件 信号量 MFC在名为CCriticalSection\CMutex\CEven ...

  9. MFC多线程各种线程用法 .

    http://blog.csdn.net/qq61394323/article/details/9328301 一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleTh ...

随机推荐

  1. position的值?

    static(默认):按照正常文档流进行排列:relative(相对定位):不脱离文档流,参考自身静态位置通过 top, bottom, left, right 定位:absolute(绝对定位):参 ...

  2. (Java实现) 洛谷 P1071 潜伏者

    题目描述 R国和 S国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动.历尽艰险后,潜伏于 S国的 R 国间谍小 C终于摸清了 S 国军用密码的编码规则: 1. S 国军方内部欲发送的原信息经过 ...

  3. Java实现 蓝桥杯VIP 算法提高 3000米排名预测

    算法提高 3000米排名预测 时间限制:1.0s 内存限制:256.0MB 问题描述 3000米长跑时,围观党们兴高采烈地预测着最后的排名.因为他们来自不同的班,对所有运动员不一定都了解,于是他们分别 ...

  4. 第九届蓝桥杯JavaB组国(决)赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.三角形面积 已知三角形三个顶点在直角坐标系下的坐标分别为: (2.3, 2.5) (6.4, 3.1) (5.1, 7.2) 求该三角 ...

  5. Linux 文件系统属性chattr权限

    chattr命令 格式:chattr [+-=] [选项] 文件或目录名,其中,+表示增加权限,-表示删除权限,=表示等于某权限(对超级用户root也有用),比如:chattr +i /project ...

  6. Linux目录结构与功能

    在Linux中,一切皆文件.所以,Linux和Windows目录有很大的不同,它没有明确的盘符,它的目录就像一棵大树一样,顶层目录就是根目录:/ ,然后下面又有很多个分支,分支可以再分,从而形成一个庞 ...

  7. 一文带你了解ANR(测试人员)

    一.首先,了解一下什么是ANR ANR,是"Application Not Responding"的缩写,即"应用程序无响应".系统会向用户显示一个对话框,用户 ...

  8. iOS-自定义 UITabBarController

    先来回顾一下UITabBarController ( 稍微详细的在在http://blog.csdn.net/yang198907/article/details/49807011) 伴随UITabB ...

  9. 死啃了String源码之后

    Java源码之String 说在前面: 为什么看源码: 最好的学习的方式就是模仿,接下来才是创造.而源码就是我们最好的模仿对象,因为写源码的人都不是一般的人,所以用心学习源码,也就可能变成牛逼的人.其 ...

  10. VMware15 镜像Centos7修改静态IP

    VMware15 镜像Centos7修改静态IP * 我的网卡名称为ens33: * 配置IP在 /etc/sysconfig/network-scripts/ifcfg-ens33 目录下: * D ...