Assim como o Java possui o ReentrantReadWriteLock, o C# possui ReaderWriterLock. Que tal então uma classe que implementa o controle de concorrência para leitura e escrita em C++ nas aplicações Windows.
English version of this article: ReadWriteLock in C++ for Windows using Mutex and Event.
A classe ReadWriteLock permite liberar acesso paralelo para threads que desejam acessar um objeto ou trecho de código somente para leitura e garante exclusividade para no caso de acesso para escrita. Código fonte abaixo:
#include <windows.h> class ReadWriteLock { public: ReadWriteLock(void); ~ReadWriteLock(void); private: HANDLE hSyncOperationsMutex; private: HANDLE hCanReadEvent; private: HANDLE hCanWriteEvent; private: HANDLE hReadGroup[2]; private: HANDLE hWriteGroup[2]; private: int readerThreads; public: void writeLock(); public: void writeUnlock(); public: void readLock(); public: void readUnlock(); }; ReadWriteLock::ReadWriteLock(void) { this->hSyncOperationsMutex = CreateMutex(NULL, FALSE, NULL); this->hCanReadEvent = CreateEvent(NULL, TRUE, TRUE, NULL); this->hCanWriteEvent = CreateEvent(NULL, TRUE, TRUE, NULL); this->hReadGroup[0] = hSyncOperationsMutex; this->hReadGroup[1] = hCanReadEvent; this->hWriteGroup[0] = hSyncOperationsMutex; this->hWriteGroup[1] = hCanWriteEvent; this->readerThreads=0; } ReadWriteLock::~ReadWriteLock(void) { CloseHandle(this->hSyncOperationsMutex); CloseHandle(this->hCanReadEvent); CloseHandle(this->hCanWriteEvent); } void ReadWriteLock::writeLock() { //wait for write flag and mutex WaitForMultipleObjects(2, this->hWriteGroup, TRUE, INFINITE); ResetEvent(this->hCanReadEvent); ResetEvent(this->hCanWriteEvent); //dont release the mutex } void ReadWriteLock::writeUnlock() { //dont get the already taken mutex SetEvent(this->hCanReadEvent); SetEvent(this->hCanWriteEvent); //release mutex ReleaseMutex(this->hSyncOperationsMutex); } void ReadWriteLock::readLock() { //wait for read flag and mutex WaitForMultipleObjects(2, this->hReadGroup, TRUE, INFINITE); //lock write operations on first thread if ( this->readerThreads == 0 ) { ResetEvent(this->hCanWriteEvent); } //increase reader count this->readerThreads++; //release mutex ReleaseMutex(this->hSyncOperationsMutex); } void ReadWriteLock::readUnlock() { //get mutex WaitForSingleObject(this->hSyncOperationsMutex, INFINITE); //decrease reader count this->readerThreads--; //unlock write operations on last reader thread if ( this->readerThreads == 0 ) { SetEvent(this->hCanWriteEvent); } //release mutex ReleaseMutex(this->hSyncOperationsMutex); }
Exemplo de uso da classe:
//cria objeto ReadWriteLock* rwLocks = new ReadWriteLock(); void LeObjetos() { rwLocks->readLock(); //nesse trecho todas as threads tem acesso simultaneo rwLocks->readUnlock(); } void AlteraObjetos() { rwLocks->writeLock(); //esse trecho é acessado por um objeto de cada vez //e também bloqueia acesso ao trecho de leitura rwLocks->writeUnlock(); }
No comments:
Post a Comment