多线程开发中经常涉及到数据的互斥访问,常用的手段之一就是使用临界区。至于用法嘛,可以参考MSDN里的例程。
// Global variable
CRITICAL_SECTION CriticalSection;
void main()
{
...
// Initialize the critical section one time only.
if (!InitializeCriticalSectionAndSpinCount(&CriticalSection,
0x80000400) )
return;
...
// Release resources used by the critical section object.
DeleteCriticalSection(&CriticalSection)
}
DWORD WINAPI ThreadProc( LPVOID lpParameter )
{
...
// Request ownership of the critical section.
EnterCriticalSection(&CriticalSection);
// Access the shared resource.
// Release ownership of the critical section.
LeaveCriticalSection(&CriticalSection);
...
}
用法还是比较简单的,开始要初始化,最后要删除。把对数据操作的部分放在EnterCriticalSection() 和 LeaveCritivalSection() 函数之间就可以了。
但是当多个函数要使用临界区时,一遍遍的EnterCriticalSection() 和 LeaveCritivalSection() 难免有大量重复代码。同时如果圈复杂度比较高的话,EnterCriticalSection() 和 LeaveCritivalSection() 有可能由于人工失误导致跨越代码块。要克服这两个问题,可以通过实现自己的互斥类来解决。
//ThreadMutex.h
#ifndef _WINDOWS_THREAD_MUTEX_H_
#define _WINDOWS_THREAD_MUTEX_H_
#pragma once
#include <windows.h>
class CThreadMutexObject
{
public:
CThreadMutexObject(DWORD dwSpinCount = 0x1000);
~CThreadMutexObject(void);
friend class CThreadMutex;
protected:
CThreadMutexObject(CThreadMutexObject & src);
CThreadMutexObject & operator = (CThreadMutexObject & src);
CRITICAL_SECTION m_cs;
};
class CThreadMutex
{
public:
CThreadMutex(CThreadMutexObject & objectMutex);
~CThreadMutex(void);
protected:
CThreadMutex(CThreadMutex & src);
CThreadMutex & operator = (CThreadMutex & src);
CRITICAL_SECTION *m_pCS;
};
#endif
//ThreadMutex.cpp
#include "ThreadMutex.h"
CThreadMutexObject::CThreadMutexObject(DWORD dwSpinCount)
{
InitializeCriticalSectionAndSpinCount(&m_cs,dwSpinCount);
}
CThreadMutexObject::~CThreadMutexObject(void)
{
DeleteCriticalSection(&m_cs);
}
CThreadMutex::CThreadMutex(CThreadMutexObject & objectMutex)
{
m_pCS = &(objectMutex.m_cs);
EnterCriticalSection(m_pCS);
}
CThreadMutex::~CThreadMutex(void)
{
LeaveCriticalSection(m_pCS);
}
使用方法
//Sample.h
...
CThreadMutexObject m_mutex;
...
//Sample.cpp
...
void Sample::MutexDemo()
{
CThreadMutex lock(m_mutex);
// Access the shared resource.
}
如果因为某些原因,我不希望互斥在在整个函数内都生效(比如说函数的执行时间可能很长)。怎么办?很简单。
void Sample::MutexDemo()
{
...
{
CThreadMutex lock(m_mutex);
// 操作共享数据
...
}
//高耗时操作
...
}