In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Most people do not understand the knowledge points of this article "case Analysis of C# Resource Pool restrictions", so the editor summarizes the following contents, detailed contents, clear steps, and has a certain reference value. I hope you can get something after reading this article, let's take a look at this "C# Resource Pool restriction case Analysis" article.
Semaphore, SemaphoreSlim class
Both can limit the number of threads accessing a resource or resource pool at the same time.
Semaphore class
Here, the API that is commonly used in the Semaphore class is listed first.
Its constructor is as follows:
The constructor explains that Semaphore (Int32, Int32) initializes a new instance of the Semaphore class and specifies the initial number of entries and the maximum number of concurrent entries. Semaphore (Int32, Int32, String) initializes a new instance of the Semaphore class and specifies the initial number of entries and the maximum number of concurrent entries, and the name of the system semaphore object as needed. Semaphore (Int32, Int32, String, Boolean) initializes a new instance of the Semaphore class and specifies the initial and maximum concurrent entries, optionally specifying the name of the system semaphore object, and specifying a variable to receive a value indicating whether a new system semaphore has been created.
Semaphore uses a pure kernel time (kernel-time) approach (with a short wait time) and supports synchronization of threads between different processes (like Mutex).
The common methods of Semaphore are as follows:
The method states that Close () releases all resources occupied by the current WaitHandle. OpenExisting (String) opens the specified name as a semaphore (if it already exists). Release () exits the semaphore and returns the previous count. Release (Int32) exits the semaphore a specified number of times and returns the previous count. TryOpenExisting (String, Semaphore) opens the semaphore with the specified name (if it already exists) and returns a value indicating whether the operation was successful. WaitOne () blocks the current thread until the current WaitHandle receives a signal. WaitOne (Int32) blocks the current thread until the current WaitHandle receives the signal, while specifying the time interval in milliseconds using a 32-bit signed integer. WaitOne (Int32, Boolean) blocks the current thread until the current WaitHandle receives the signal, using a 32-bit signed integer to specify the time interval and whether to exit the synchronization domain before waiting. WaitOne (TimeSpan) blocks the current thread until the current instance receives a signal and uses TimeSpan to specify the time interval. WaitOne (TimeSpan, Boolean) blocks the current thread until the current instance receives the signal, using TimeSpan to specify the time interval and whether to exit the synchronization domain before waiting. Example
Let's write the code directly, using the example in "Atomic manipulation Interlocked". Now we require that multiple threads perform the calculation, but only a maximum of three threads are allowed to run at the same time.
There are four steps to using Semaphore:
New instantiates Semaphore and sets the maximum number of threads and the number of threads that can be entered during initialization
Use .WaitOne (); to get access (the thread is in a blocking state until it is granted).
Use Release () to release occupancy when leaving.
Close () releases the Semaphore object.
The example in "Atomic manipulation Interlocked" improves as follows:
Class Program {/ / summation private static int sum = 0; private static Semaphore _ pool; / / determines whether ten threads have ended. Private static int isComplete = 0; / / the first program static void Main (string [] args) {Console.WriteLine ("execute program") / / set to allow a maximum of three threads to enter the resource pool / / initially set to 0, that is, several threads are allowed to enter during initialization / / set to 0 here, and then release three threads _ pool = new Semaphore (0,3); for (int I = 0; I) when the key is pressed
< 10; i++) { Thread thread = new Thread(new ParameterizedThreadStart(AddOne)); thread.Start(i + 1); } Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("任意按下键(不要按关机键),可以打开资源池"); Console.ForegroundColor = ConsoleColor.White; Console.ReadKey(); // 准许三个线程进入 _pool.Release(3); // 这里没有任何意义,就单纯为了演示查看结果。 // 等待所有线程完成任务 while (true) { if (isComplete >= 10) break; Thread.Sleep (TimeSpan.FromSeconds (1));} Console.WriteLine ("sum =" + sum); / / release pool _ pool.Close () } public static void AddOne (object n) {Console.WriteLine ($"thread {(int) n} start, enter the queue"); / / enter the queue and wait for _ pool.WaitOne (); Console.WriteLine ($"the {(int) n} thread enters the resource pool") / / enter the resource pool for (int I = 0; I
< 10; i++) { Interlocked.Add(ref sum, 1); Thread.Sleep(TimeSpan.FromMilliseconds(500)); } // 解除占用的资源池 _pool.Release(); isComplete += 1; Console.WriteLine($" 第{(int)n}个线程退出资源池"); } } 看着代码有点多,快去运行一下,看看结果。 示例说明 实例化 Semaphore 使用了new Semaphore(0,3); ,其构造函数原型为 public Semaphore(int initialCount, int maximumCount); initialCount 表示一开始允许几个进程进入资源池,如果设置为0,所有线程都不能进入,要一直等资源池放通。 maximumCount 表示最大允许几个线程进入资源池。 Release() 表示退出信号量并返回前一个计数。这个计数指的是资源池还可以进入多少个线程。 可以看一下下面的示例: private static Semaphore _pool; static void Main(string[] args) { _pool = new Semaphore(0, 5); _pool.Release(5); new Thread(AddOne).Start(); Thread.Sleep(TimeSpan.FromSeconds(10)); _pool.Close(); } public static void AddOne() { _pool.WaitOne(); Thread.Sleep(1000); int count = _pool.Release(); Console.WriteLine("在此线程退出资源池前,资源池还有多少线程可以进入?" + count); }信号量 前面我们学习到 Mutex,这个类是全局操作系统起作用的。我们从 Mutex 和 Semphore 中,也看到了 信号量这个东西。 信号量分为两种类型:本地信号量和命名系统信号量。 命名系统信号量在整个操作系统中均可见,可用于同步进程的活动。 局部信号量仅存在于进程内。 当 name 为 null 或者为空时,Mutex 的信号量时局部信号量,否则 Mutex 的信号量是命名系统信号量。 Semaphore 的话,也是两种情况都有。 如果使用接受名称的构造函数创建 Semaphor 对象,则该对象将与该名称的操作系统信号量关联。 两个构造函数: Semaphore(Int32, Int32, String)Semaphore(Int32, Int32, String, Boolean) 上面的构造函数可以创建多个表示同一命名系统信号量的 Semaphore 对象,并可以使用 OpenExisting 方法打开现有的已命名系统信号量。 我们上面使用的示例就是局部信号量,进程中引用本地 Semaphore 对象的所有线程都可以使用。 每个 Semaphore 对象都是单独的本地信号量。 SemaphoreSlim类 SemaphoreSlim 跟 Semaphore 有啥关系? 微软文档: SemaphoreSlim 表示对可同时访问资源或资源池的线程数加以限制的 Semaphore 的轻量替代。 SemaphoreSlim 不使用信号量,不支持进程间同步,只能在进程内使用。 它有两个构造函数: 构造函数说明SemaphoreSlim(Int32)初始化 SemaphoreSlim 类的新实例,以指定可同时授予的请求的初始数量。SemaphoreSlim(Int32, Int32)初始化 SemaphoreSlim 类的新实例,同时指定可同时授予的请求的初始数量和最大数量。示例 我们改造一下前面 Semaphore 中的示例: class Program { // 求和 private static int sum = 0; private static SemaphoreSlim _pool; // 判断十个线程是否结束了。 private static int isComplete = 0; static void Main(string[] args) { Console.WriteLine("执行程序"); // 设置允许最大三个线程进入资源池 // 一开始设置为0,就是初始化时允许几个线程进入 // 这里设置为0,后面按下按键时,可以放通三个线程 _pool = new SemaphoreSlim(0, 3); for (int i = 0; i < 10; i++) { Thread thread = new Thread(new ParameterizedThreadStart(AddOne)); thread.Start(i + 1); } Console.WriteLine("任意按下键(不要按关机键),可以打开资源池"); Console.ReadKey(); // _pool.Release(3); // 这里没有任何意义,就单纯为了演示查看结果。 // 等待所有线程完成任务 while (true) { if (isComplete >= 10) break; Thread.Sleep (TimeSpan.FromSeconds (1));} Console.WriteLine ("sum =" + sum); / / release pool} public static void AddOne (object n) {Console.WriteLine ($"Thread {(int) n} start, queue") / / enter the queue and wait for _ pool.Wait (); Console.WriteLine ($"the {(int) n} thread enters the resource pool"); / / enter the resource pool for (int I = 0; I < 10; iqueue +) {Interlocked.Add (ref sum, 1) Thread.Sleep (TimeSpan.FromMilliseconds);} / / unoccupied resource pool _ pool.Release (); isComplete + = 1; Console.WriteLine ($"{(int) n} thread exit resource pool");}}
Close () is not required for SemaphoreSlim.
The difference in code between the two is as simple as that.
Difference
If you instantiate Semaphor with the following constructor (the parameter name cannot be empty), the object created is valid throughout the operating system.
Public Semaphore (int initialCount, int maximumCount, string name)
Semaphorslim is only valid within the process.
The SemaphoreSlim class does not enforce thread or task identities on calls to Wait, WaitAsync, and Release methods.
The Semaphor class will strictly monitor this, and an exception will occur if the number of corresponding calls is inconsistent.
In addition, if you use the SemaphoreSlim (Int32 maximumCount) constructor to instantiate a SemaphoreSlim object to get its CurrentCount property, its value may be greater than maximumCount. The programmer is responsible for ensuring that a Wait or WaitAsync method is called and a Release is called.
This is like the pen in the penholder, there is no monitoring, after the use of this, you should put the pen into it. If there were 10 pens that were not put in each use, or if pens from other places were put in, then the final number would not be 10.
The above is the content of this article on "case Analysis of C# Resource Pool restrictions". I believe we all have some understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.