For the code, if one considers using RAII to encapsulate CriticalSection
(global scope), two RAII layers are needed: InitializeCriticalSection
layer (main function scope), enter EnterCriticalSection
layer (multi-thread based Proc scope).
// Global variable
CRITICAL_SECTION CriticalSection;
int main( void )
{
// Initialize the critical section one time only.
if (!InitializeCriticalSection(&CriticalSection) )
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);
return 1;
}
As CriticalSection
and the two layers all have different scopes, and also enter InitializeCriticalSection
layer must be on top of EnterCriticalSection
layer.
class CriticalSectionGuard {
public:
CriticalSectionGuard(CRITICAL_SECTION * cs) : m_CS(cs) {
InitializeCriticalSection(m_CS);
}
~CriticalSectionGuard() {
DeleteCriticalSection(m_CS);
}
void lock() {
EnterCriticalSection(m_CS);
}
void unlock{
LeaveCriticalSection(m_CS);
}
private:
CRITICAL_SECTION * m_CS;
}
class GetLock {
public:
GetLock(CriticalSectionGuard* plock) : m_csg(plock) {
m_csg->lock();
}
~GetLock(void) {
m_csg->unlock();
}
private:
CriticalSectionGuard * m_csg;
};
// Global variable
CRITICAL_SECTION CriticalSection;
int main(void)
{
// Initialize the critical section one time only.
CriticalSectionGuard CSG(&CriticalSection);
...
}
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
// we need pass along the CSG Pointer, which is messy.
GetLock(&CSG);
...
return 1;
}
It looks quite bad, as the CriticalSectionGuard
object is not in the global scope, it need pass along to threads.
Please share any suggestions or criticisms to improve the code.