临界区锁 InitializeCriticalSection()--- EnterCriticalSection()--LeaveCriticalSection()
2016-12-05 16:04
537 查看
[+]
此函数初始化一个临界区对象。
格式:
void InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection);
参数:lpCriticalSection指向临界区对象的指针。
返回值:无
单个进程的线程可以使用一个互斥同步临界区对象。虽然对线程将获得临界区所有权的顺序没有保证,该系统将处理所有线程的所有权要求。
这个进程负责分配一个临界区对象使用的内存,它可以通过声明类型的CRITICAL_SECTION的变量使用的内存。在使用一个临界区对象以前,一些进程中的线程必须调用InitializeCriticalSection函数来初始化对象。
一旦一个临界区对象已被初始化,该进程的线程可以在EnterCriticalSection或LeaveCriticalSection函数指定对象,提供对共享资源的相互独占式访问。对于不同进程之间的类似线程同步,使用互斥对象。
一个临界区对象不能移动或复制。这一进程也绝不能修改该对象,但必须把它作为逻辑不透明来处理。只能使用由与Microsoft Win32 ® API提供的临界区功能,用来管理临界区对象。
在低内存的情况下,InitializeCriticalSection可能提出STATUS_NO_MEMORY异常。
========
删除关键节对象释放由该对象使用的所有系统资源。
3、线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法
注:使用结构CRITICAL_SECTION 需加入头文件#include “afxmt.h”
定义一个全局的锁 CRITICAL_SECTION的实例
和一个静态全局变量
CRITICAL_SECTION cs;//可以理解为锁定一个资源
static int n_AddValue = 0;//定义一个静态的全部变量n_AddValue
创建两个线程函数,代码实现如下:
//第一个线程
UINT FirstThread(LPVOID lParam)
{
EnterCriticalSection(&cs);//加锁
接下来的代码处理过程中不允许其他线程进行操作,除非遇到LeaveCriticalSection
for(int i = 0; i<10; i++){
n_AddValue ++;
cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;
}
LeaveCriticalSection(&cs);//解锁
到EnterCriticalSection之间代码资源已经释放了,其他线程可以进行操作
return 0;
}
//第二个线程
UINT SecondThread(LPVOID lParam)
{
EnterCriticalSection(&cs);//加锁
for(int i = 0; i<10; i++){
n_AddValue ++;
cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
}
LeaveCriticalSection(&cs);//解锁
return 0;
}
在主函数添加以下代码
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL,
::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: MFC
初始化失败/n"));
nRetCode = 1;
}
else
{
InitializeCriticalSection(&cs);//初始化结构CRITICAL_SECTION
CWinThread *pFirstThread,*pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针
pFirstThread = AfxBeginThread(FirstThread,LPVOID(NULL));//启动第一个线程
pSecondThread = AfxBeginThread(SecondThread,LPVOID(NULL));//启动第二个线程
HANDLE hThreadHandle[2];//
hThreadHandle[0] = pFirstThread->m_hThread;
hThreadHandle[1] = pSecondThread->m_hThread;
//等待线程返回
WaitForMultipleObjects(2,hThreadHandle,TRUE,INFINITE);
}
return nRetCode;
}
输出:
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循环中去,线程的执行顺序将会改变
输出也就跟着改变,如:
//第一个线程
UINT FirstThread(LPVOID lParam)
{
for(int i = 0; i<10; i++){
EnterCriticalSection(&cs);//加锁
锁移到for循环内部里
n_AddValue ++;
cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;
LeaveCriticalSection(&cs);//解锁
}
return 0;
}
//第二个线程
UINT SecondThread(LPVOID lParam)
{
for(int i = 0; i<10; i++){
EnterCriticalSection(&cs);//加锁
n_AddValue ++;
cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
LeaveCriticalSection(&cs);//解锁
}
return 0;
}
其他代码不变,输出的结果如下:
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中间的代码执行过程不会被其他线程干拢或者这么讲不允许其他线程中
的代码执行。这样可以有效防止一个全局变量在两个线程中同时被操作的可能性
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的实例
和一个静态全局变量
CRITICAL_SECTION cs;//可以理解为锁定一个资源
static int n_AddValue = 0;//定义一个静态的全部变量n_AddValue
创建两个线程函数,代码实现如下:
//第一个线程
UINT FirstThread(LPVOID lParam)
{
EnterCriticalSection(&cs);//加锁
接下来的代码处理过程中不允许其他线程进行操作,除非遇到LeaveCriticalSection
for(int i = 0; i<10; i++){
n_AddValue ++;
cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;
}
LeaveCriticalSection(&cs);//解锁
到EnterCriticalSection之间代码资源已经释放了,其他线程可以进行操作
return 0;
}
//第二个线程
UINT SecondThread(LPVOID lParam)
{
EnterCriticalSection(&cs);//加锁
for(int i = 0; i<10; i++){
n_AddValue ++;
cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
}
LeaveCriticalSection(&cs);//解锁
return 0;
}
在主函数添加以下代码
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL,
::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: MFC
初始化失败/n"));
nRetCode = 1;
}
else
{
InitializeCriticalSection(&cs);//初始化结构CRITICAL_SECTION
CWinThread *pFirstThread,*pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针
pFirstThread = AfxBeginThread(FirstThread,LPVOID(NULL));//启动第一个线程
pSecondThread = AfxBeginThread(SecondThread,LPVOID(NULL));//启动第二个线程
HANDLE hThreadHandle[2];//
hThreadHandle[0] = pFirstThread->m_hThread;
hThreadHandle[1] = pSecondThread->m_hThread;
//等待线程返回
WaitForMultipleObjects(2,hThreadHandle,TRUE,INFINITE);
}
return nRetCode;
}
输出:
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循环中去,线程的执行顺序将会改变
输出也就跟着改变,如:
//第一个线程
UINT FirstThread(LPVOID lParam)
{
for(int i = 0; i<10; i++){
EnterCriticalSection(&cs);//加锁
锁移到for循环内部里
n_AddValue ++;
cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;
LeaveCriticalSection(&cs);//解锁
}
return 0;
}
//第二个线程
UINT SecondThread(LPVOID lParam)
{
for(int i = 0; i<10; i++){
EnterCriticalSection(&cs);//加锁
n_AddValue ++;
cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
LeaveCriticalSection(&cs);//解锁
}
return 0;
}
其他代码不变,输出的结果如下:
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()--- EnterCriticalSection()--LeaveCriticalSection()
- 临界区锁 InitializeCriticalSection()--- EnterCriticalSection()--LeaveCriticalSection()
- 临界区锁 InitializeCriticalSection()--- EnterCriticalSection()--LeaveCriticalSection()
- 临界区的api原型 EnterCriticalSection和 LeaveCriticalSection
- Windows API一日一练(46)EnterCriticalSection和LeaveCriticalSection函数
- 理解EnterCriticalSection 临界区
- 线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法
- Windows API一日一练(46)EnterCriticalSection和LeaveCriticalSection函数
- 理解EnterCriticalSection 临界区
- 理解EnterCriticalSection 临界区
- Windows API一日一练(46)EnterCriticalSection和LeaveCriticalSection函数
- 理解EnterCriticalSection 临界区
- 理解EnterCriticalSection 临界区
- 线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法
- 线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法 .
- Windows API一日一练(46)EnterCriticalSection和LeaveCriticalSection函数
- EnterCriticalSection 与 LeaveCriticalSection
- Windows API一日一练(46)EnterCriticalSection和LeaveCriticalSection函数
- 理解EnterCriticalSection 临界区
- 理解EnterCriticalSection 临界区