Implement read/write locks and read/write locks
Exclusive lock disadvantagesData is shared among multiple threads. The common practice is to lock read/write, that is, only one thread can read or write data at the same time point to ensure data consistency, that is, thread security. For example, the following pseudocode is a common practice.
1 void Read () 2 {3 Lock (mutex); 4 5 // Read data 6 7 UnLock (mutex); 8} 9 10 void Write () 11 {12 Lock (mutex); 13 14 // write data 15 16 UnLock (mutex); 17}
Design of read/write locks
Such locks are exclusive and will affect the efficiency of the program to a certain extent. Assume that multiple threads compete to obtain the Read and Write rights. Obviously, only one thread can obtain the permission at the same time, either reading or writing, and between reading and reading operations, or between a write operation and a write operation, it is also exclusive and has the following relationships: 1. read-write, exclusive 2. Write-write, exclusive 3. Read-read, since exclusive locks affect program efficiency, how can we optimize it? Exclusive lock aims to avoid such competition conditions. Before a thread completes the read operation, another thread's write operation changes the data or multiple threads perform the write operation at the same time. Apparently, there is an exclusive requirement between read and write operations, or between write and write operations, while exclusive locks bring in negative effects, read operations and read operations are exclusive. Here, we can imagine what problems the read/write lock can solve. Yes, it is to avoid this negative impact and satisfy the following relationship 1. read-write, exclusive 2. Write-write, exclusive 3. Read-read. Sharing simply means that multiple threads can simultaneously perform read operations. The idea is as follows (pseudocode)
1 void Read () 2 {3 Wait (condition); 4 5 Lock (mutex); 6 if (0 = Count ++) 7 Lock (semaphore ); 8 UnLock (mutex); 9 10 // read data 11 12 Lock (mutex); 13 if (0 = -- Count) 14 UnLock (semaphore); 15 UnLock (mutex ); 16} 17 18 void Write () 19 {20 Destroy (condition); 21 Lock (semaphore); 22 23 // Write data 24 25 UnLock (semaphore ); 26 Create (condition); 27}
In the code, the initial value of semaphore is 1. In order to read-write, the relationship between exclusive and write-write exclusive is exclusive. Count records the number of read operations, while mutex aims to ensure the security of the Count thread. Ignore the Code related to condition. It can be said that the read/write lock mentioned above has been implemented. But why does it add condition? The reason is that if multiple threads Perform continuous read operations, the write operation may not be performed for a long time, that is, the write lock is usually called hunger. Condition can solve this problem. If a thread is waiting for a write operation, the new read operation waits until the write operation is complete. This ensures that the access to read and write operations is relatively fair.
Implemented in WindowsRead/write lock
On Windows, Vista and Server 2008 and later versions start to provide read/write lock-related APIs. To support the XP system, you must implement the read/write lock mechanism on your own. I have already introduced how to implement read/write locks. I don't need to talk about it here, so I can directly post the code.
1 // implement Code 2 3 class RWLock 4 {5 public: 6 RWLock (); 7 ~ RWLock (); 8 public: 9 void AcquireReadLock (); 10 void ReleaseReadLock (); 11 void AcquireWriteLock (); 12 void ReleaseWriteLock (); 13 private: 14 volatile DWORD m_cnt; 15 CRITICAL_SECTION m_cs; 16 HANDLE m_evt; 17 HANDLE m_sem; 18}; 19 20 RWLock: RWLock () 21: m_cnt (0) 22, m_evt (NULL) 23, m_cs (NULL) 24, m_sem (NULL) 25 {26 // recommended practices create and initialize these variables 27 28: InitializeCriticalSection (& m_cs) in a dedicated initialization function ); 29 30 // The Event must be manually reset Otherwise, there is a deadlock risk, that is, 31 m_evt =: CreateEvent (NULL, TRUE, TRUE, NULL) is activated before waiting for the Event; 32 m_sem =: CreateSemaphore (NULL, 1, 1, NULL); 33} 34 35 RWLock ::~ RWLock () 36 {37: CloseHandle (m_sem); 38: CloseHandle (m_evt); 39: DeleteCriticalSection (& m_cs); 40} 41 42 void RWLock :: acquireReadLock () 43 {44: WaitForSingleObject (m_evt, INFINITE); 45 46: EnterCriticalSection (& m_cs); 47 if (0 = m_cnt ++) 48 :: waitForSingleObject (m_sem, INFINITE); 49: LeaveCriticalSection (& m_cs); 50} 51 52 void RWLock: ReleaseReadLock () 53 {54: EnterCriticalSection (& m_cs ); 55 if (0 = -- m_cnt) 56: ReleaseSemaphore (m_sem, 1, NULL); 57: LeaveCriticalSection (& m_cs); 58} 59 60 void RWLock :: acquireWriteLock () 61 {62: ResetEvent (m_evt); 63: WaitForSingleObject (m_sem, INFINITE); 64} 65 66 void RWLock: ReleaseWriteLock () 67 {68 :: releaseSemaphore (m_sem, 1, NULL); 69: SetEvent (m_evt); 70} 71 72 // use example 73 74 void Read () 75 {76 // multiple threads can simultaneously perform read Operations 77 78 rwLock. acquireReadLock (); 79 80 // read data 81 82 rwLock. releaseReadLock (); 83} 84 85 void Write () 86 {87 rwLock. acquireWriteLock (); 88 89 // write data 90 91 rwLock. releaseWriteLock (); 92}View Code
Copyright Disclaimer: This article is the original author of the blog, please respect the author's hard code word results, reprinted please indicate the link http://www.cnblogs.com/coldberry/p/ReadWriteLock.html