How to enter and leave the critical section?

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?!
[789 byte] By [xander_tan] at [2007-11-18 17:43:21]
# 1 Re: How to enter and leave the critical section?
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
}
}
Andreas Masur at 2007-11-9 13:55:56 >