CRITICAL_SECTION 的作用是保护资源
《windows核心编程》中有介绍。还有一个厕所的例子
把厕所看作一个资源,每个人进去前要看看厕所是否有人(EnterCriticalSection),
如果有人就需要等待,直到里面人离开(LeaveCriticalSection),外面的人才能进去。
如果访问资源之前不 EnterCriticalSection ,那就相当于直接用脚踹开厕所门,不管里面有没有人。
另外,考虑下面的代码
static CRITICAL_SECTION cs ;
void fun()
{
EnterCriticalSection (&cs) ;
// 一些操作 ……
// 此处抛出异常
//
//
LeaveCriticalSection (&cs) ;
}
如果函数退出时没有 LeaveCriticalSection ,那么下一个 EnterCriticalSection (&cs) 将一直等待。
所以,最好封装一下,在类初始化中 EnterCriticalSection ,析构函数中 LeaveCriticalSection
下面是一个简单的例子(只封装了 EnterCriticalSection 和 LeaveCriticalSection ,没有初始化……):
class CAutoLock
{
public:
CAutoLock(CRITICAL_SECTION* pCS):m_pCS(pCS)
{
EnterCriticalSection (m_pCS);
}
~CAutoLock()
{
LeaveCriticalSection (m_pCS) ;
}
CRITICAL_SECTION* m_pCS;
};
static CRITICAL_SECTION cs ;
void fun()
{
CAutoLock lock(&cs) ;
// 一些操作 ……
}
关于多线程同步的几点疑问(以CRITICAL_SECTION 为例)
楼主可能对同步机制不是很了解。
我举个例子看看,也许对你有帮助。
全局变量 int num[10];
线程函数
{
for(int i=0;i<10;i++)
num[i] = var;
}
如果在两个线程同时调用 setvalue(1) ,setvalue(2),有可能出现在线程一的for i= 5的时候,开始执行线程 2的for()循环。 这时等两个函数都运行结束的时候,全局变量的值就不是你需要的结果了。
如果要解决这个问题,就需要加上CRITICAL_SECTION
CRITICAL_SECTION m_sec;
InitCrit.....
{
EnterCriticalSection(&m_sec);
for(int i=0;i<10;i++)
num[i] = var;
LeaveCriticalSection(&m_sec);
}
这时,线程一在执行for里面的循环时,如果windows切换到了线程2运行setvalue()函数,线程2在执行EnterCriticalSection(&m_sec);时就会阻塞,等待线程1执行了Leave时候才会继续执行。
另外,EnterCriticalSection()里面的变量需要是同一个时才会出现互斥。
如果需要分别访问多个互斥资源时,应该定义多个互斥量