必威体育Betway必威体育官网
当前位置:首页 > IT技术

临界区锁 InitializeCriticalSection()--- EnterCriticalSection()--LeaveCriticalSection()

时间:2019-06-02 12:43:03来源:IT技术作者:seo实验室小编阅读:77次「手机版」
 

initializecriticalsection

1、

initializecriticalsection

函数初始化一个临界区对象。

格式:

void InitializeCriticalSection(  LPcritical_section lpCriticalSection);

参数:lpCriticalSection指向临界区对象的指针

返回值:无

单个进程的线程可以使用一个互斥同步临界区对象。虽然对线程将获得临界区所有权的顺序没有保证,该系统将处理所有线程的所有权要求。

这个进程负责分配一个临界区对象使用的内存,它可以通过声明类型的CRITICAL_SECTION的变量使用的内存。在使用一个临界区对象以前,一些进程中的线程必须调用InitializeCriticalSection函数来初始化对象。

一旦一个临界区对象已被初始化,该进程的线程可以在entercriticalsection或LeaveCriticalSection函数指定对象,提供对共享资源的相互独占式访问。对于不同进程之间的类似线程同步,使用互斥对象。

一个临界区对象不能移动或复制。这一进程也绝不能修改该对象,但必须把它作为逻辑不透明来处理。只能使用由与Microsoft Win32 ® API提供的临界区功能,用来管理临界区对象。

在低内存的情况下,InitializeCriticalSection可能提出STATUS_NO_MEMORY异常。

========

2、DeleteCriticalSection

删除关键节对象释放由该对象使用的所有系统资源。

  void WINAPI DeleteCriticalSection(_Inout_ LPCRITICAL_SECTION lpCriticalSection);

参数:  lpCriticalSection, 对关键节对象的指针。先前必须已将该对象初始化与InitializeCriticalSection函数中。

=================

3、线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法

注:使用结构CRITICAL_SECTION 需加入头文件#include “afxmt.h”

定义一个全局的锁 CRITICAL_SECTION的实例

和一个静态全局变量

  1. CRITICAL_SECTION cs;//可以理解为锁定一个资源
  2. static int n_AddValue = 0;//定义一个静态的全部变量n_AddValue

创建两个线程函数,代码实现如下:

  1. //第一个线程
  2. UINT FirstThread(LPVOID lParam)
  3. {
  4.     EnterCriticalSection(&cs);//加锁 接下来的代码处理过程中不允许其他线程进行操作,除非遇到LeaveCriticalSection
  5.     for(int i = 0; i<10; i++){       
  6.         n_AddValue ++;
  7.         cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;       
  8.    
  9.     }
  10.     LeaveCriticalSection(&cs);//解锁 到EnterCriticalSection之间代码资源已经释放了,其他线程可以进行操作   
  11.     return 0;
  12.  
  13. }
  14.  
  15. //第二个线程
  16. UINT SecondThread(LPVOID lParam)
  17. {
  18.     EnterCriticalSection(&cs);//加锁
  19.     for(int i = 0; i<10; i++){       
  20.         n_AddValue ++;       
  21.         cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;   
  22.        
  23.     }
  24.     LeaveCriticalSection(&cs);//解锁
  25.  
  26.     return 0;
  27.  
  28. }

在主函数添加以下代码

  1. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  2. {
  3.     int nRetCode = 0;
  4.  
  5.     // 初始化 MFC 并在失败时显示错误
  6.     if (!AfxWinInit(::GetModulehandle(NULL), NULL, ::GetcommandLine(), 0))
  7.     {
  8.         // TODO: 更改错误代码以符合您的需要
  9.         _tprintf(_T("错误: MFC 初始化失败/n"));
  10.         nRetCode = 1;
  11.     }
  12.     else
  13.     {
  14.  
  15.         InitializeCriticalSection(&cs);//初始化结构CRITICAL_SECTION
  16.  
  17.  
  18.         CWinThread *pFirstThread,*pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针
  19.        
  20.  
  21.         pFirstThread  = AfxBeginThread(FirstThread,LPVOID(NULL));//启动第一个线程
  22.         pSecondThread = AfxBeginThread(SecondThread,LPVOID(NULL));//启动第二个线程
  23.  
  24.         HANDLE hThreadHandle[2];//
  25.         hThreadHandle[0] = pFirstThread->m_hThread;
  26.         hThreadHandle[1] = pSecondThread->m_hThread;
  27.  
  28.         //等待线程返回
  29.         waitforMultipleObjects(2,hThreadHandle,TRUE,INFINITE);       
  30.     }
  31.  
  32.     return nRetCode;
  33. }

输出:

n_AddValue in FirstThread is 1

n_AddValue in FirstThread is 2

n_AddValue in FirstThread is 3

n_AddValue in FirstThread is 4

n_AddValue in FirstThread is 5

n_AddValue in FirstThread is 6

n_AddValue in FirstThread is 7

n_AddValue in FirstThread is 8

n_AddValue in FirstThread is 9

n_AddValue in FirstThread is 10

n_AddValue in SecondThread is 11

n_AddValue in SecondThread is 12

n_AddValue in SecondThread is 13

n_AddValue in SecondThread is 14

n_AddValue in SecondThread is 15

n_AddValue in SecondThread is 16

n_AddValue in SecondThread is 17

n_AddValue in SecondThread is 18

n_AddValue in SecondThread is 19

n_AddValue in SecondThread is 20

如果把两个线程函数中的EnterCriticalSection和LeaveCriticalSection位置移到for循环中去,线程的执行顺序将会改变

输出也就跟着改变,如:

  1. //第一个线程
  2. UINT FirstThread(LPVOID lParam)
  3. {
  4.    
  5.     for(int i = 0; i<10; i++){
  6.         EnterCriticalSection(&cs);//加锁 锁移到for循环内部里
  7.         n_AddValue ++;
  8.         cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;   
  9.         LeaveCriticalSection(&cs);//解锁 
  10.     }   
  11.     return 0;
  12. }
  13.  
  14. //第二个线程
  15. UINT SecondThread(LPVOID lParam)
  16. {
  17.    
  18.     for(int i = 0; i<10; i++){   
  19.         EnterCriticalSection(&cs);//加锁
  20.         n_AddValue ++;       
  21.         cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
  22.         LeaveCriticalSection(&cs);//解锁       
  23.     }
  24.     return 0;
  25. }

其他代码不变,输出的结果如下:

n_AddValue in FirstThread is 1

n_AddValue in SecondThread is 2

n_AddValue in FirstThread is 3

n_AddValue in SecondThread is 4

n_AddValue in FirstThread is 5

n_AddValue in SecondThread is 6

n_AddValue in FirstThread is 7

n_AddValue in SecondThread is 8

n_AddValue in FirstThread is 9

n_AddValue in SecondThread is 10

n_AddValue in FirstThread is 11

n_AddValue in SecondThread is 12

n_AddValue in FirstThread is 13

n_AddValue in SecondThread is 14

n_AddValue in FirstThread is 15

n_AddValue in SecondThread is 16

n_AddValue in FirstThread is 17

n_AddValue in SecondThread is 18

n_AddValue in FirstThread is 19

n_AddValue in SecondThread is 20

个人认为在函数EnterCriticalSection和LeaveCriticalSection中间的代码执行过程不会被其他线程干拢或者这么讲不允许其他线程中

的代码执行。这样可以有效防止一个全局变量在两个线程中同时被操作的可能性

相关阅读

临界区锁 InitializeCriticalSection()--- EnterCriti

1、 InitializeCriticalSection 此函数初始化一个临界区对象。格式:void InitializeCriticalSection(  LPCRITICAL_SECTION l

C++ 线程同步之临界区CRITICAL_SECTION

一、临界区临界区又称关键代码段,指的是一小段代码在代码执行前,他需要独占一些资源。程序中通常将多线程同时访问的某个资源作为临

分享到:

栏目导航

推荐阅读

热门阅读