[Disclaimer: All Rights Reserved. You are welcome to reprint it. Do not use it for commercial purposes. Contact Email: feixiaoxing @ 163.com]
When writing multiple threads, there is a common situation. That is, there are few opportunities to modify some public data. Compared with rewriting, they have much higher read opportunities. In general, the process of reading is often accompanied by the search operation, which takes a long time in the middle. Locking such code segments will greatly reduce the efficiency of our programs. Is there a way to handle this situation with more reads and less writes?
Yes, that is, the read/write lock.
(1) first, Let's define the basic data structure.
typedef struct _RWLock{ int count; int state; HANDLE hRead; HANDLE hWrite;}RWLock;
In addition, to determine whether the current lock is in the read or write status, we need to define an enumeration volume,
typedef enum{ STATE_EMPTY = 0, STATE_READ, STATE_WRITE};
(2) initialize the Data Structure
RWLock* create_read_write_lock(HANDLE hRead, HANDLE hWrite){ RWLock* pRwLock = NULL; assert(NULL != hRead && NULL != hWrite); pRwLock = (RWLock*)malloc(sizeof(RWLock)); pRwLock->hRead = hRead; pRwLock->hWrite = hWrite; pRwLock->count = 0; pRwLock->state = STATE_EMPTY; return pRwLock;}
(3) Get the read lock
void read_lock(RWLock* pRwLock){ assert(NULL != pRwLock); WaitForSingleObject(pRwLock->hRead, INFINITE); pRwLock->counnt ++; if(1 == pRwLock->count){ WaitForSingleObject(pRwLock->hWrite, INFINITE); pRwLock->state = STATE_READ; } ReleaseMutex(pRwLock->hRead);}
(4) Get the write lock
void write_lock(RWLock* pRwLock){ assert(NULL != pRwLock); WaitForSingleObject(pRwLock->hWrite, INFINITE); pRwLock->state = STATE_WRITE;}
(5) release the read/write lock
void read_write_unlock(RWLock* pRwLock){ assert(NULL != pRwLock); if(STATE_READ == pRwLock->state){ WaitForSingleObject(pRwLock->hRead, INFINITE); pRwLock->count --; if(0 == pRwLock->count){ pRwLock->state = STATE_EMPTY; ReleaseMutex(pRwLock->hWrite); } ReleaseMutex(pRwLock->hRead); }else{ pRwLock->state = STATE_EMPTY; ReleaseMutex(pRwLock->hWrite); } return;}
Summary:
(1) the advantage of the read/write lock can be maximized only when multiple reads and less writes and the code segment runs for a long time;
(2) Any modification to public data must be completed in the lock;
(3) The read/write lock has its own application location. It is very important to select an appropriate application environment;
(4) writing a read/write lock is prone to errors. You should exercise more;
(5) read locks and write locks must be used separately; otherwise, the effect cannot be achieved.