博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows线程同步(一):临界区对象
阅读量:2193 次
发布时间:2019-05-02

本文共 1757 字,大约阅读时间需要 5 分钟。

http://blog.csdn.net/beyondhaven/article/details/7000871

为什么使用线程同步?

同步可以保证在一个时间内只有一个线程对某个资源(如操作系统资源等共享资源)有控制权。共享资源包括全局变量、公共数据成员或者句柄等。同步还可以使得有关联交互作用的代码按一定的顺序执行。

线程同步的方式?

同步对象有:CRITICAL_SECTION (临界区),Event(事件),Mutex(互斥对象),Semaphores(信号量)。

本文重点讲解CRITICAL_SECTION (临界区)。

临界区,说白了,就是“锁”。看过星爷的《破坏王》的朋友都知道,那个送外卖的小子,就是靠自创绝招“无敌风火轮”将大师兄打败,抱得美人归。“无敌风火轮”的本质就是:锁!

怎么锁?

这里有四个关键函数:InitializeCriticalSection  EnterCriticalSection  LeaveCriticalSection  DeleteCriticalSection来完成此机制。

使用临界区对象的时候,首先要定义一个临界区对象CriticalSection:

CRITICAL_SECTION CriticalSection;

然后,初始化该对象:InitializeCriticalSection(&CriticalSection);

如果一段程序代码需要对某个资源进行同步保护,则这是一段临界区代码。在进入该临界区代码前调用EnterCriticalSection函数,这样,其他线程都不能执行该段代码,若它们试图执行就会被阻塞。

完成临界区的执行之后,调用LeaveCriticalSection函数,其他的线程就可以继续执行该段代码。


简要实例

下面的代码中,如果不加CRITICAL_SECTION ,有可能造成在线程1给data设置完名字后,线程2给data设置年龄,造成了数据紊乱,所以有必要使用同步机制,将其锁住,保证数据的安全。

[cpp]  
 
  1. class Data  
  2. {  
  3. private:  
  4.     CString Name;  
  5.     int Age;  
  6. public:  
  7.     void SetName(const CString& name)  
  8.     {  
  9.         Name = name;  
  10.     }  
  11.       
  12.     void SetAge(int age)  
  13.     {  
  14.         Age = age;  
  15.     }  
  16.       
  17.     void GetName(CString &name)  
  18.     {  
  19.         name = Name;  
  20.     }  
  21.       
  22.     void GetAge(int &age)  
  23.     {  
  24.         age = Age;  
  25.     }  
  26. };  
  27.   
  28. Data g_data; //全局变量  
  29. CRITICAL_SECTION CriticalSection;   
  30.   
  31. //线程函数  
  32. DWORD WINAPI ThreadProc( LPVOID lpParameter )  
  33. {  
  34.     EnterCriticalSection(&CriticalSection);   
  35.     data.SetName("赵星星");  
  36.     data.SetAge(20);  
  37.     LeaveCriticalSection(&CriticalSection);  
  38. }  
  39.   
  40. int main()  
  41. {  
  42.   
  43.     InitializeCriticalSection(&CriticalSection);   
  44.       
  45.     //创建线程,执行线程函数  
  46.     //......  
  47.       
  48.     DeleteCriticalSection(&CriticalSection);  
  49.   
  50.     return 0;  
  51. }  
真锁?假锁?

可以定义CRITICAL_SECTION 数组:CRITICAL_SECTION g_Critical[10];

CRITICAL_SECTION 没有超时的概念,如果函数LeaveCriticalSection不被调用,则其他线程将无限期的等待。容易造成死锁。

CRITICAL_SECTION 属于轻量级的线程同步对象,相对于mutex来说,它的效率会高很多。mutex可以用于进程之间的同步,CRITICAL_SECTION只在同一个进程有效。

实际上,CRITICAL_SECTION 锁的是代码段,如果代码段中有对资源的占用,只是间接的锁住了该资源,我们也可以称之为“假锁”。

参考:

1、《MFC教程》

2、 

你可能感兴趣的文章
【Loadrunner】【浙江移动项目手写代码】代码备份
查看>>
Python几种并发实现方案的性能比较
查看>>
[Jmeter]jmeter之脚本录制与回放,优化(windows下的jmeter)
查看>>
Jmeter之正则
查看>>
【JMeter】1.9上考试jmeter测试调试
查看>>
【虫师】【selenium】参数化
查看>>
【Python练习】文件引用用户名密码登录系统
查看>>
学习网站汇总
查看>>
【Python】用Python打开csv和xml文件
查看>>
【Loadrunner】性能测试报告实战
查看>>
【自动化测试】自动化测试需要了解的的一些事情。
查看>>
【selenium】selenium ide的安装过程
查看>>
【手机自动化测试】monkey测试
查看>>
【英语】软件开发常用英语词汇
查看>>
Fiddler 抓包工具总结
查看>>
【雅思】雅思需要购买和准备的学习资料
查看>>
【雅思】雅思写作作业(1)
查看>>
【雅思】【大作文】【审题作业】关于同不同意的审题作业(重点)
查看>>
【Loadrunner】通过loadrunner录制时候有事件但是白页无法出来登录页怎么办?
查看>>
【English】【托业】【四六级】写译高频词汇
查看>>