Click to See Complete Forum and Search --> : How to enter and leave the critical section?
xander_tan
March 10th, 2004, 07:43 AM
void main()
{
_beginthread(threadA,0,NULL);
_beginthread(threadB,0,NULL);
_endthread();
}
void threadA(void* dummy)
{
for(int i = 0; i < 10; i++)
cout << "testA" << endl;
}
void threadB(void* dummy)
{
for(int i = 0; i < 10; i++)
cout << "testB" << endl;
}
Want to try to print "testA" and "testB" alternately.
testA
testB
testA
.
.
.
testB
But it failed.
I read a book about multithreading. It's written about the critical section. I'm trying to apply it. I've looked for the function in MSDN, there are EnterCriticalSection and LeaveCriticalSection.
How to use it? Or I cannot use it? Any other function?!
Andreas Masur
March 10th, 2004, 08:03 AM
Well...okay...the stream output (cout etc.) is not designed for being used in multithreaded environments without adding some kind of synchronization. Thus, you need to protect the shared resource properly. This is where you can use a critical section for example...
The following is an example which basically accesses a global variable from two threads and also follows the RAII (Resource acquisition is initialization) idiom...
class CSync
{
public:
CSync() { InitializeCriticalSection(&m_CriticalSection); }
~CSync() { DeleteCriticalSection(&m_CriticalSection); }
void Acquire() { EnterCriticalSection(&m_CriticalSection); }
void Release() { LeaveCriticalSection(&m_CriticalSection); }
private:
CRITICAL_SECTION m_CriticalSection; // Synchronization object
};
class CLockGuard
{
public:
CLockGuard(CSync &refSync) : m_refSync(refSync) { Lock(); }
~CLockGuard() { Unlock(); }
private:
CSync &m_refSync; // Synchronization object
CLockGuard(const CLockGuard &refcSource);
CLockGuard &operator=(const CLockGuard &refcSource);
void Lock() { m_refSync.Acquire(); }
void Unlock() { m_refSync.Release(); }
};
This can be used as follows...
int iGlobalInt = 10;
CSync GlobalSync;
// Thread 1
CLockGuard Gate(GlobalSync);
iGlobalInt = 12;
// Thread 2
CLockGuard Gate(GlobalSync);
iGlobalInt = 22;
The 'iGlobalInt' here is the 'cout' in your example. However, that makes only sure, that one thread at a time will write to the 'cout' stream. It does not produce necessarely the wished result of alternating outputs. For getting this, you would also need to provide some events which gets triggered alternatingly...for example...
void threadA(void* dummy)
{
for(int i = 0; i < 10; i++)
{
// Reset event (Wait event)
// CLockGuard
cout << "testA" << endl;
// Set event for thread B
// Wait for event from thread B
}
}
void threadB(void* dummy)
{
for(int i = 0; i < 10; i++)
{
// Reset event (Wait event)
// CLockGuard
cout << "testB" << endl;
// Set event for thread A
// Wait for event from thread A
}
}
codeguru.com
Copyright WebMediaBrands Inc., All Rights Reserved.