The concept of read-write locks is simple, allowing multiple threads to acquire read locks at the same time, but only one thread is allowed to obtain write locks at the same time, so it is also called shared-exclusive locks. In C#, it is recommended to use the ReaderWriterLockSlim class to complete the read/write lock function. In some cases, the number of reads to an object is much greater than the number of modifications, and if it is simply locked by locking, it will affect the efficiency of reading. If a read-write lock is used, multiple threads can read the object at the same time, and it will only be blocked when the object is occupied by the write-lock. Simply put, when a thread enters read mode, other threads can still enter read mode, assuming that a thread wants to enter write mode at this time, then it has to be blocked. until read mode exits. Similarly, if a thread goes into write mode, the other threads will be blocked whether they want to write or read. There are 2 ways to enter write/read mode: EnterReadLock attempts to enter the write mode lock state. TryEnterReadLock(Int32) attempts to enter the read mode lock state, with the option to select an integer timeout. EnterWriteLock attempts to enter the Write Mode Lock state. TryEnterWriteLock(Int32) attempts to enter the write mode lock state, and the timeout time can be selected. There are 2 ways to exit write/read mode: ExitReadLock reduces the recursive count of the read mode and exits the read mode when the resulting count is 0 (zero). ExitWriteLock reduces the recursive count of the write pattern and exits the write mode when the resulting count is 0 (zero). Here's how to use it:
You can see that thread 3 and thread 4 can enter read mode at the same time, while thread 5 can enter write mode after 5 seconds (that is, after threads 3 and 4 exit the read lock). Modify the above code, first open 2 threads in write mode, and then open threads in read mode, the code is as follows:
The results are as follows:
As you can see, thread 3 and thread 4 both enter write mode, but thread 3 occupies the write lock first, so thread 4 has to wait 10s before entering. Threads 5 and 6 need to occupy the read lock, so wait for thread 4 to exit the write lock before continuing. TryEnterReadLock and TryEnterWriteLock can set a timeout, when running to this sentence, the thread will block here, if the lock can be occupied at this time, then return true, if the timeout time has not yet occupied the lock, then return false, give up the occupation of the lock, and continue to execute the following code directly. EnterUpgradeableReadLock The ReaderWriterLockSlim class provides an upgradeable read mode, which differs from read mode in that it can also be upgraded to write mode by calling the EnterWriteLock or TryEnterWriteLock methods. Because only one thread can be in upgradeable mode at a time. A thread that enters upgradable mode will not affect the thread in read mode, that is, when a thread enters upgradable mode, any number of threads can enter read mode at the same time without blocking. If multiple threads are already waiting to acquire a write lock, running EnterUpgradeableReadLock will block until those threads time out or exit the write lock. The following code shows how to upgrade to a write lock in upgradable read mode.
The impact of read/write locks on performance is obvious. The following test code:
The above code simulates the operation of 500 Tasks, each of which occupies a thread pool thread, of which 20 are write threads and 480 read threads are simulated. It takes 10 ms to read data and 100 ms to write to test the lock method and the ReaderWriterLockSlim method respectively. An estimate can be made, for ReaderWriterLockSlim, assuming that 480 threads read at the same time, then it consumes 10ms, 20 write operations occupy 2000ms, so the time consumed is 2010ms, and for the ordinary lock method, because they are all exclusive, so 480 read operations occupy 4800ms + 20 write operations 2000ms = 6800ms. The results showed a noticeable performance improvement.
|