当前位置:网站首页>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 .
边栏推荐
- 21 examples of strategic goals to promote the rapid development of your company
- Introduction to neural network (Part 2)
- With excellent strength, wangchain technology, together with IBM and Huawei, has entered the annual contribution list of "super ledger"!
- L1-025 positive integer a+b (15 points)
- Basic DOS commands
- 2022-021ARTS:下半年開始
- 博客停更声明
- BUUCTF(4)
- A real penetration test
- Write a thread pool by hand, and take you to learn the implementation principle of ThreadPoolExecutor thread pool
猜你喜欢
The frost peel off the purple dragon scale, and the xiariba people will talk about database SQL optimization and the principle of indexing (primary / secondary / clustered / non clustered)
BUUCTF(3)
[Flink] temporal semantics and watermark
如何用MOS管来实现电源防反接电路
Detailed introduction to the big changes of Xcode 14
Google's official response: we have not given up tensorflow and will develop side by side with Jax in the future
NPM run build error
[test de performance] lire jmeter
[gurobi] establishment of simple model
Devops Practice Guide - reading notes (long text alarm)
随机推荐
window上用.bat文件启动项目
弈柯莱生物冲刺科创板:年营收3.3亿 弘晖基金与淡马锡是股东
在所有SwiftUI版本(1.0-4.0)中原生实现Charts图表视图之思路
Basic DOS commands
Rapidjson reading and writing JSON files
Routing decorator of tornado project
Write a thread pool by hand, and take you to learn the implementation principle of ThreadPoolExecutor thread pool
Advanced MySQL: Basics (5-8 Lectures)
[network security] what is emergency response? What indicators should you pay attention to in emergency response?
What determines vacuum permittivity and vacuum permeability? Why do these two physical quantities exist?
猜数字游戏
L1-028 judging prime number (10 points)
21个战略性目标实例,推动你的公司快速发展
In the era of low code development, is it still needed?
深入浅出:了解时序数据库 InfluxDB
1、卡尔曼滤波-最佳的线性滤波器
NPM run build error
谷歌官方回应:我们没有放弃TensorFlow,未来与JAX并肩发展
JVM中堆概念
I was pressed for the draft, so let's talk about how long links can be as efficient as short links in the development of mobile terminals