当前位置:网站首页>Example analysis of C # read / write lock
Example analysis of C # read / write lock
2022-07-04 07:46:00 【Yisu cloud】
C# Example analysis of read-write lock
Today I'd like to share with you C# Relevant knowledge points of read-write lock instance analysis , Detailed content , Clear logic , I believe most people still know too much about this knowledge , So share this article for your reference , I hope you will gain something after reading this article , Now let's take a look .
ReaderWriterLockSlim
ReaderWriterLock class : Define locks that support a single write thread and multiple read threads .
ReaderWriterLockSlim class : Represents the locked state used to manage resource access , It can realize multi thread read or exclusive write access .
Of the two API Very close , and ReaderWriterLockSlim relative ReaderWriterLock Come on More secure . So this article mainly explains ReaderWriterLockSlim .
Both are to realize that multiple threads can read at the same time 、 Classes that only one thread is allowed to write to .
ReaderWriterLockSlim
Old rules , Let's get a general idea of ReaderWriterLockSlim Common methods .
Common methods
Method | explain |
---|---|
EnterReadLock() | Try to enter the read mode lock state . |
EnterUpgradeableReadLock() | Try to enter the upgradeable mode lock state . |
EnterWriteLock() | Try to enter the write mode lock state . |
ExitReadLock() | Reduce the recursive count of read mode , And when the generated count is 0( zero ) Exit read mode when . |
ExitUpgradeableReadLock() | Reduce the recursive count of upgradeable patterns , And when the generated count is 0( zero ) Exit upgradeable mode when . |
ExitWriteLock() | Reduce the recursive count of write mode , And when the generated count is 0( zero ) Exit write mode when . |
TryEnterReadLock(Int32) | Try to enter the read mode lock state , You can choose an integer timeout . |
TryEnterReadLock(TimeSpan) | Try to enter the read mode lock state , You can choose the timeout . |
TryEnterUpgradeableReadLock(Int32) | Try to enter the upgradeable mode lock state , You can choose the timeout . |
TryEnterUpgradeableReadLock(TimeSpan) | Try to enter the upgradeable mode lock state , You can choose the timeout . |
TryEnterWriteLock(Int32) | Try to enter the write mode lock state , You can choose the timeout . |
TryEnterWriteLock(TimeSpan) | Try to enter the write mode lock state , You can choose the timeout . |
ReaderWriterLockSlim The reading of 、 Write lock template as follows :
private static ReaderWriterLockSlim toolLock = new ReaderWriterLockSlim(); // read private T Read() { try { toolLock.EnterReadLock(); // Get read lock return obj; } catch { } finally { toolLock.ExitReadLock(); // Release the read lock } return default; } // Write public void Write(int key, int value) { try { toolLock.EnterUpgradeableReadLock(); try { toolLock.EnterWriteLock(); /* * */ } catch { } finally { toolLock.ExitWriteLock(); } } catch { } finally { toolLock.ExitUpgradeableReadLock(); } }
Example of order system
Here we simulate a simple and rough order system .
Before you start writing code , Let's first understand the specific use of some methods .
EnterReadLock()
/ TryEnterReadLock
and ExitReadLock()
Pairs appear .
EnterWriteLock()
/ TryEnterWriteLock()
and ExitWriteLock()
Pairs appear .
EnterUpgradeableReadLock()
Enter the upgradeable read mode lock state .
EnterReadLock()
Use EnterUpgradeableReadLock()
Enter upgrade state , At the right time adopt EnterWriteLock()
Enter write mode .( It can also be reversed )
Define three variables :
ReaderWriterLockSlim Multithread read write lock ;
MaxId Current order Id The maximum of ;
orders The order sheet ;
private static ReaderWriterLockSlim tool = new ReaderWriterLockSlim(); // Read-write lock private static int MaxId = 1; public static List<DoWorkModel> orders = new List<DoWorkModel>(); // The order sheet
// Order model public class DoWorkModel { public int Id { get; set; } // The order number public string UserName { get; set; } // Customer name public DateTime DateTime { get; set; } // Creation time }
And then realize the two methods of query and order creation .
Query orders by page :
Use... Before reading EnterReadLock()
Get the lock ;
After reading , Use ExitReadLock()
Release the lock .
In this way, we can ensure that each read is the latest value in a multithreaded environment .
// Query orders by page private static DoWorkModel[] DoSelect(int pageNo, int pageSize) { try { DoWorkModel[] doWorks; tool.EnterReadLock(); // Get read lock doWorks = orders.Skip((pageNo - 1) * pageSize).Take(pageSize).ToArray(); return doWorks; } catch { } finally { tool.ExitReadLock(); // Release the read lock } return default; }
Create order :
The information for creating an order is very simple , Just know the user name and creation time .
The order system should guarantee that every Id It's all unique ( The actual situation should use Guid), Here to demonstrate the read-write lock , Set to Numbers .
In multithreaded environment , We don't use Interlocked.Increment()
, But directly += 1
, Because there are read-write locks , So the operation is also principled .
// Create order private static DoWorkModel DoCreate(string userName, DateTime time) { try { tool.EnterUpgradeableReadLock(); // upgrade try { tool.EnterWriteLock(); // Acquire write lock // Write order MaxId += 1; // Interlocked.Increment(ref MaxId); DoWorkModel model = new DoWorkModel { Id = MaxId, UserName = userName, DateTime = time }; orders.Add(model); return model; } catch { } finally { tool.ExitWriteLock(); // Release write lock } } catch { } finally { tool.ExitUpgradeableReadLock(); // Downgrade } return default; }
Main In the method :
open 5 Threads , Keep reading , open 2 A thread keeps creating orders . The thread is not set when creating an order Thread.Sleep()
Of , So it runs very fast .
Main The code in the method is meaningless .
static void Main(string[] args) { // 5 Thread reads for (int i = 0; i < 5; i++) { new Thread(() => { while (true) { var result = DoSelect(1, MaxId); if (result is null) { Console.WriteLine(" Acquisition failure "); continue; } foreach (var item in result) { Console.Write($"{item.Id}|"); } Console.WriteLine("\n"); Thread.Sleep(1000); } }).Start(); } for (int i = 0; i < 2; i++) { new Thread(() => { while(true) { var result = DoCreate((new Random().Next(0, 100)).ToString(), DateTime.Now); // Simulate order generation if (result is null) Console.WriteLine(" Create failure "); else Console.WriteLine(" Create success "); } }).Start(); } }
stay ASP.NET Core in , You can use the read-write lock , Solve the problem of multi-user sending at the same time HTTP Database read and write problems caused by requests .
I won't do an example here .
If another thread has a problem , Cause delay in handing over the write lock , This may cause other threads to wait indefinitely .
Then you can use TryEnterWriteLock()
And set the waiting time , Avoid blocking for too long .
bool isGet = tool.TryEnterWriteLock(500);
Examples of concurrent dictionary writing
Because theoretical things , I won't say too much here , The main thing is to master some API( Method 、 attribute ) Use , Then write a simple example , Let's get to know the underlying principles later .
Let's write a multi thread shared usage dictionary (Dictionary) Use example of .
Add two static variables :
private static ReaderWriterLockSlim toolLock = new ReaderWriterLockSlim(); private static Dictionary<int, int> dict = new Dictionary<int, int>();
Implement a write operation :
public static void Write(int key, int value) { try { // Upgrade status toolLock.EnterUpgradeableReadLock(); // read , Check for presence if (dict.ContainsKey(key)) return; try { // Enter the write state toolLock.EnterWriteLock(); dict.Add(key,value); } finally { toolLock.ExitWriteLock(); } } finally { toolLock.ExitUpgradeableReadLock(); } }
There is no catch { }
It's for a better look at the code , Because a read-write lock is used , There should be no problem in theory .
Simulate five threads writing dictionary at the same time , Because it's not an atomic operation , therefore sum Sometimes there are duplicate values .
private static int sum = 0; public static void AddOne() { for (int i = 0; i < 100_0000; i++) { sum += 1; Write(sum,sum); } } static void Main(string[] args) { for (int i = 0; i < 5; i++) new Thread(() => { AddOne(); }).Start(); Console.ReadKey(); }
ReaderWriterLock
Most of the time it's recommended ReaderWriterLockSlim Of , And the use of the two is very close .
for example AcquireReaderLock It's getting the read lock ,AcquireWriterLock Get write lock . Use the corresponding method to replace ReaderWriterLockSlim Example in .
It's not right here ReaderWriterLock I'm going to go over it .
ReaderWriterLock The common methods are as follows :
Method | explain |
---|---|
AcquireReaderLock(Int32) | Use one Int32 The timeout value gets the read thread lock . |
AcquireReaderLock(TimeSpan) | Use one TimeSpan The timeout value gets the read thread lock . |
AcquireWriterLock(Int32) | Use one Int32 The timeout value gets the write thread lock . |
AcquireWriterLock(TimeSpan) | Use one TimeSpan The timeout value gets the write thread lock . |
AnyWritersSince(Int32) | Indicates whether the write thread lock has been granted to a thread after obtaining the serial number . |
DowngradeFromWriterLock(LockCookie) | Restore the thread's lock state to call UpgradeToWriterLock(Int32) The former state . |
ReleaseLock() | Release the lock , No matter how many times a thread gets a lock . |
ReleaseReaderLock() | Reduce lock count . |
ReleaseWriterLock() | Reduce the lock count on the write thread lock . |
RestoreLock(LockCookie) | Restore the thread's lock state to call ReleaseLock() The former state . |
UpgradeToWriterLock(Int32) | Use one Int32 The timeout value upgrades the read thread lock to the write thread lock . |
UpgradeToWriterLock(TimeSpan) | Use one TimeSpan The timeout value upgrades the read thread lock to the write thread lock . |
That's all “C# Example analysis of read-write lock ” All the content of this article , Thank you for reading ! I believe you will gain a lot after reading this article , Xiaobian will update different knowledge for you every day , If you want to learn more , Please pay attention to the Yisu cloud industry information channel .
边栏推荐
- Zephyr study notes 2, scheduling
- MYCAT middleware installation and use
- 【性能測試】一文讀懂Jmeter
- 如何用MOS管来实现电源防反接电路
- In the era of low code development, is it still needed?
- Used on windows Bat file startup project
- How to send mail with Jianmu Ci
- BUUCTF(3)
- How to improve your system architecture?
- L1-027 rental (20 points)
猜你喜欢
Chrome is set to pure black
Unity-Text上标平方表示形式+text判断文本是否为空
如何用MOS管来实现电源防反接电路
1、卡尔曼滤波-最佳的线性滤波器
博客停更声明
It's healthy to drink medicinal wine like this. Are you drinking it right
zabbix监控系统邮件报警配置
Routing decorator of tornado project
Do you know about autorl in intensive learning? A summary of articles written by more than ten scholars including Oxford University and Google
Système de surveillance zabbix contenu de surveillance personnalisé
随机推荐
2022-021rts: from the second half of the year
运动【跑步 01】一个程序员的半马挑战:跑前准备+跑中调整+跑后恢复(经验分享)
Comparison between applet framework and platform compilation
Write a thread pool by hand, and take you to learn the implementation principle of ThreadPoolExecutor thread pool
How to improve your system architecture?
Improve the accuracy of 3D reconstruction of complex scenes | segmentation of UAV Remote Sensing Images Based on paddleseg
Basic DOS commands
墨者学院-phpMyAdmin后台文件包含分析溯源
BUUCTF(4)
Jianmu continuous integration platform v2.2.2 release
The idea of implementing charts chart view in all swiftui versions (1.0-4.0) was born
Leetcode 146. LRU 缓存
Zephyr 学习笔记1,threads
Leetcode (215) -- the kth largest element in the array
墨者学院-PHPMailer远程命令执行漏洞溯源
Rhcsa the next day
Go h*ck yourself:online reconnaissance (online reconnaissance)
Div hidden in IE 67 shows blank problem IE 8 is normal
Zephyr learning notes 1, threads
L1-022 odd even split (10 points)