首页 迪士尼彩乐园1入口 迪士尼彩乐园官方客服

迪士尼彩乐园官方客服

你的位置:迪士尼彩乐园 > 迪士尼彩乐园官方客服 > 迪士尼彩乐园官网首页 并发编程 - 线程同步(九)之信号量Semaphore

迪士尼彩乐园官网首页 并发编程 - 线程同步(九)之信号量Semaphore

发布日期:2025-02-17 02:57    点击次数:59

前边对自旋锁SpinLock进行了详实学习,今天咱们将学习另一个种同步机制——信号量Semaphore。

多数玩家不同意这个观点,他们解释说,在这种短片中人物设计是为了配合场景情感表达,并且考虑到不是同一世和不同年龄段的因素,容貌变化是合理的。还有人认为这只是动画风格的选择,并无必要过于纠结。

第一局,9分钟,LGD的公孙离击败夏洛特拿到第一滴血。10分钟,MD拿到暗影暴君,LGD逼团,最后双方打了3换3。11分钟,LGD拿到暗影主宰,经济反超。15分钟,梦奇击败夏侯惇,随后顺势拿下暗影双龙,LGD拿到巨大优势。16分钟,LGD依靠龙兵破三高,司空震拿到二连击破,随后LGD点破水晶,先下一城。

01、信号量是什么?

在 C# 中,信号量(Semaphore)是一种用于线程同步的机制,大要界限对分享资源的窥伺。它的责任旨趣是通过爱戴一个计数器来界限对资源的窥伺次数。它常用于截止对分享资源(如数据库联络池、文献系统、收集资源等)的并发窥伺。

1、信号量有三个中枢见地:

1.计数:信号量的中枢是一个计数器,示意现时资源的可用数目;

2.恭候:当线程央求资源时,这次要是计数器大于0,则线程不错不绝实行,同期计数器减1;要是计数器等于0,则线程被阻止直至其他线程开释资源,即有线程加多计数器的值;

3.开释:当线程使用完资源后,则需要开释信号量,同期计数器加1,并叫醒其他恭候的线程;

坚信兼并了信号量中枢见地,其责任旨趣就不言而谕。

2、诳骗场景:

通过对信号量的责任旨趣了解,咱们不错记忆为:信号量等于为了界限对分享资源的窥伺,保证分享资源不会被过度使用,因此不错彭胀出以下适用于信号量的场景:

1.界限各式联络池:截止同期翻开各式资源的联络数目(比如联络打印机数目,数据库联络数据,文献窥伺数目);

2.截止收集央求:提神劳动器过载,导致劳动器崩溃;

3.伙同多个线程的实行规章:通过信号量界限生成者和蹧跶者之间的资源窥伺, 收场分娩者和蹧跶者模子;

02、C#中的信号量收场

C#提供了两种信号量类型:Semaphore和SemaphoreSlim。其中两者功能基本相易,却又有所不同,而SemaphoreSlim是更轻量、更快速的信号量收场。底下是两种简便相比:

Semaphore:是基于系统内核收场,属于内核级别同步,相沿跨程度资源同步,迪士尼彩乐园1入口因此性能较低,内存占用较大;它不错一次开释多个信号量,然则莫得提供原生的异步相沿;

SemaphoreSlim:是用户级别同步,并不依赖系统内核,因此不相沿跨程度资源同步,因此性能更高,内存占用更低;它一次只可开释一个信号量,然则提供了原生异步相沿;

03、Semaphore使用示例

通过对信号量旨趣的详实了解,而行为对信号量收场类Semaphore,这些旨趣也一样适用,因此Semaphore类的构造函数就指定了用于界限线程数目的参数。其构造函数如下:

public Semaphore(int initialCount, int maximumCount);public Semaphore(int initialCount, int maximumCount, string name);

initialCount: 运行化信号量的计数,示意运行时不错同期窥伺资源的线程数目。

maximumCount: 信号量的最大计数,示意允许同期窥伺资源的最大线程数。

name: 可选的称呼,用于定名信号量对象(可在多个程度间分享信号量)。

然后不错用WaitOne设施得到信号量,使用Release设施开释信号量。

底下咱们作念一个小例子,创建一个运行化为2个线程的信号量Semaphore,然后启动5个线程用来窥伺信号量,并在得到信号量之前、之后以及开释信号量之前王人加上日记,用来不雅察线程被界限的历程。代码如下:

public class SemaphoreExample{ //运行化最多2个线程同期投入, 最大允许3个线程 private static Semaphore semaphore = new Semaphore(2, 3); //用于不同的线程披露不同的神采,便捷不雅察收尾 private static ConsoleColor[] colors = new ConsoleColor[5] { ConsoleColor.Red, ConsoleColor.White, ConsoleColor.Yellow, ConsoleColor.Green, ConsoleColor.Blue }; public static void Worker(object? i) { var id = (int)i; var color = colors[id]; PrintText.SafeForegroundColor($"线程 {id} 恭候投入...", color); //央求投入信号量(要是资源弗成用,则复返) semaphore.WaitOne; PrintText.SafeForegroundColor($"线程 {id} 已 [ 投入 ] 同步代码块.", color); //业务责罚 Thread.Sleep(2000); PrintText.SafeForegroundColor($"线程 {id} 已 [ 离开 ] 同步代码块.", color); //开释信号量(让其他线程不错投入) semaphore.Release; }} public static void SemaphoreRun{ for (int i = 0; i

咱们沿途望望实行收尾:

不错发面前红框部分为所有这个词线程运行化完成,同期独一两个线程得到到信号量,之后等于又一个信号量开释得胜,则紧随着一个恭候线程会立马投入,直到所有这个词线程责罚完成。

到这里会有一个疑问,咱们在运行化信号量Semaphore时,指定了最大允许3个线程不错同期投入,然则上头示例并莫得体现出来,这是为什么呢?

这是因为在信号量的生命周期中,maximumCount参数并不会顺利变调信号量确现时可用资源数目,而是截止并发线程数的最大值。因此要是要思看到成果,则需要经过稀奇责罚才行,比如咱们在上头的代码中开释信号量时,咱们实行两次开释操作,然则这么会导致终末开释操作报SemaphoreFullException极度,因此要详实得到和开释信号量操作要配对,这里只是为了演示,实行收尾如下:

不错看到maximumCount最大窥伺线程数顺利了。

04、Semaphore使用详实事项

1.确保每个调用 WaitOne设施 的线程最终王人会调用 Release设施。不然,可能会导致死锁。

2.确保Release设施的调用次数不应跨越 WaitOne设施的调用次数,不然会抛出 SemaphoreFullException极度

3.要是单程度设施尽量聘请SemaphoreSlim,因为SemaphoreSlim性能更好。

4.要是需要跨程度同步不错使用带称呼的构造函数 Semaphore(int initialCount, int maximumCount, string name)。

注:测试设施代码以及示例源码王人依然上传至代码库迪士尼彩乐园官网首页,有风趣的不错望望。https://gitee.com/hugogoos/Planner