This article is based on the previous articles, since we'll use the mutex and semaphore in our class. This artical will mainly be consisted by the C++ code, not too many words.
#include <windows.h>
class Lock
{
public:
Lock()
{
hMutex = CreateMutex(NULL, false, "OWNLOCK");
hSemaphore = CreateSemaphore(NULL, 1, 1, "OWNSEMAPHORE");
iReaderCount = 0;
}
void AcquireReadLock()
{
WaitForSingleObject(hMutex, INFINITE);
if(++iReaderCount == 1)
WaitForSingleObject(hSemaphore, INFINITE);
ReleaseMutex(hMutex);
}
void ReleaseReadLock()
{
WaitForSingleObject(hMutex, INFINITE);
if(--iReaderCount == 0)
ReleaseSemaphore(hSemaphore, 1, NULL);
ReleaseMutex(hMutex);
}
void AcquireWriteLock()
{
WaitForSingleObject(hSemaphore, INFINITE);
}
void ReleaseWriteLock()
{
ReleaseSemaphore(hSemaphore, 1, NULL);
}
private:
HANDLE hMutex;
HANDLE hSemophore;
int iReaderCount;
};
Regarding when to use the lock, I'm saying that if the data is shared between threads, any access to this piece of data should be protected, locked. Also using the right type of lock is also necessary, otherwise it will be the bottleneck of your application.
Another issue is that at which granularity to add the lock. My suggestion is that don't add too many locks at one time, which will cause hard to locate the problems if it happens. You should at as few locks as possiable at one time.