www.pudn.com > claar.zip > RWTEST.CPP
// Multiple-reader/Single-writer Lock in Windows NT // Demonstration Application // Author: Jeff Claar #define STRICT #define WIN32_LEAN_AND_MEAN #include#include #include #include #include "rwlock.hpp" // Event used to inform threads to terminate. HANDLE gTerminateEvent; // The read thread. This thread simulates a reader that // obtains a shared lock. It holds the lock for a few // seconds, then releases it. DWORD CALLBACK sReadThread(LPVOID rwLock) { SyRWLock* pLock = (SyRWLock *) rwLock; DWORD dwId = GetCurrentThreadId(); // Loop until the user presses ENTER. while (WaitForSingleObject(gTerminateEvent, 0) == WAIT_TIMEOUT) { printf("Read thread %d trying to get shared\n", dwId); pLock->GetShared(TRUE); printf("Read thread %d got shared\n", dwId); // Got the shared lock. Sleep for a few seconds. // Other read threads can acquire a shared lock // at this point, but no write threads can // acquire an exclusive lock. Sleep((3000 * rand()) / RAND_MAX); printf("Read thread %d releasing shared\n", dwId); pLock->Release(); // Not holding any lock. Sleep again. Sleep((1000 * rand()) / RAND_MAX); } return 0; } // The write thread. This thread simulates a writer that // obtains an exclusive lock. It holds the lock for // a few seconds, then releases it. DWORD CALLBACK sWriteThread(LPVOID rwLock) { SyRWLock* pLock = (SyRWLock *) rwLock; DWORD dwId = GetCurrentThreadId(); while (WaitForSingleObject(gTerminateEvent, 0) == WAIT_TIMEOUT) { printf("Write thread %d trying to get exclusive\n", dwId); pLock->GetExclusive(TRUE); // Now have the exclusive lock. Get a shared lock too // just to show it can be done. pLock->GetShared(TRUE); printf("Write thread %d got exclusive\n", dwId); // Sleep for a moment. No read threads // can obtain the lock at this point. Sleep((4000 * rand()) / RAND_MAX); printf("Write thread %d releasing exclusive\n", dwId); // Release the lock. We must release the lock twice // because it was acquired twice. pLock->Release(); pLock->Release(); // Sleep for a moment again while not holding // any lock. Sleep((3000 * rand()) / RAND_MAX); } return 0; } extern "C" int main(int argc, char* argv[]) { srand(time(NULL)); if (argc != 3) { printf("Usage: rwtest \n"); return -1; } int numReaders = atoi(argv[1]); int numWriters = atoi(argv[2]); printf("Press to quit.\n"); // Create the MRSW resource that will be used be this // application. SyRWLock rwl; // Create an event to inform threads to terminate. gTerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // Create the read and write threads. The // MRSW lock is passed as an argument to the thread. HANDLE* hThreads = new HANDLE[numReaders + numWriters]; DWORD id; int i; for (i = 0; i < numReaders; i++) { hThreads[i] = CreateThread(NULL, 0, sReadThread, &rwl, 0, &id); } for (i = 0; i < numWriters; i++) { hThreads[i + numReaders] = CreateThread(NULL, 0, sWriteThread, &rwl, 0, &id); } // Wait for the user to press ENTER. getchar(); // Inform the threads that they should terminate. SetEvent(gTerminateEvent); printf("Waiting for threads to terminate...\n"); WaitForMultipleObjects(numReaders + numWriters, hThreads, TRUE, INFINITE); // Close handles and exit. for (i = 0; i < numReaders + numWriters; i++) { CloseHandle(hThreads[i]); } delete [] hThreads; CloseHandle(gTerminateEvent); return 0; }