ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C# Semaphore类 [杏鑫登录]

2022-04-10 10:31:06  阅读:164  来源: 互联网

标签:again Task 杏鑫 C# Semaphore task Timeout semaphore wait


杏鑫登录

信号量非常类似于互斥,其区别是,信号量可以同时由多个线程使用。信号量是一种计数的互斥锁定。使用信号量,可以定义允许同时访问受旗语锁定保护的资源的线程个数。如果需要限制可以访问可用资源的线程数,信号量就很有用。例如,如果系统有 3 个物理端口可用,就允许 3 个线程同时访问 I/O 端口,但第 4 个线程需要等待前 3 个线程中的一个释放资源。

 

.NET Core 为信号量功能提供了两个类 Semaphore 和SemaphoreSlim。Semaphore 类可以命名,使用系统范围内的资源,允许在不同进程之间同步。SemaphoreSlim 类是对较短等待时间进行了优化的轻型版本。

在下面的示例应用程序中,在Main()方法中创建了 6 个任务和一个计数为 3 的信号量。在 Semaphore 类的构造函数中,定义了锁定个数的计数,它可以用信号量(第二个参数)来获得,还定义了最初释放的锁定数(第一个参数)。如果第一个参数的值小于第二个参数,它们的差就是已经分配线程的计数值。与互斥一样,也可以给信号量指定名称,使之在不同的进程之间共享。这里定义信号量时没有指定名称,所以它只能在这个进程中使用。在创建了 SemaphoreSlim 对象之后,启动 6个任务,它们都获得了相同的信号量。

class Program
{
  static void Main()
  {
    int taskCount = 6;
    int semaphoreCount = 3;
    var semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount);
    var tasks = new Task[taskCount];
    for (int i = 0; i < taskCount; i++)
    {
      tasks[i] = Task.Run(() => TaskMain(semaphore));
    }
    Task.WaitAll(tasks);
    Console.WriteLine("All tasks finished");
  }
  //...

 

 

在任务的主方法 TaskMain() 中,任务利用 Wait() 方法锁定信号量。信号量的计数是 3,所以有 3 个任务可以得锁定。第 4 个任务必须等待,这里还定义了最长的等待时间为 600 毫秒。如果在该等待时间过后未能获得,任务就把一条消息写入控制台,在循环中继续等待。只要获得了锁定,线程就把一条消息写入控制台,眠一段时间,然后解除锁定。在解除锁定时,在任何情况下一定要解除资源的锁定,这一点很重要。这就是在 finally 处理程序中调用 SemaphoreSlim 类的 Release() 方法的原因。

//...
public static void TaskMain(SemaphoreSlim semaphore)
{
  bool isCompleted = false; 
  while (!isCompleted)
  {
    if(semaphore.Wait(600))
    {
      try
      {
        Console.WriteLine($"Task {Task.CurrentId} locks the semaphore"); 
        Task.Delay(2000).Wait();
      }
      finally
      {
        Console.WriteLine($"Task {Task.CurrentId} releases the semaphore"); 
        semaphore.Release(); 
        isCompleted = true;
      }
    }
    else
    {
      Consloe.WriteLine($"Timeout for task {Task.CurrentID}; wait again");
    }
  }
}

  

 

 

 

 

运行应用程序,可以看到有 4 个线程很快被锁定。ID为 7、8和9 的线程需要等待。该等待会重复进行,直到其中一个被锁定的线程解除了信号量。

Task 4 locks the semaphore 
Task 5 locks the semaphore 
Task 6 locks the semaphore
Timeout for task 7; wait again 
Timeout for task 7; wait again 
Timeout for task 8; wait again 
Timeout for task 7; wait again 
Timeout for task 8; wait again
Timeout for task 7; wait again 
Timeout for task 9; wait again 
Timeout for task 8; wait again 
Task 5 releases the semaphore 
Task 7 locks the semaphore
Task 6 releases the semaphore 
Task 4 releases the semaphore 
Task 8 locks the semaphore 
Task 9 locks the semaphore
Task 8 releases the semaphore 
Task 7 releases the semaphore 
Task 9 releases the semaphore 
All tasks finished

 

杏鑫登录
Task 4 locks the semaphore Task 5 locks the semaphore Task 6 locks the semaphoreTimeout for task 7; wait again Timeout for task 7; wait again Timeout for task 8; wait again Timeout for task 7; wait again Timeout for task 8; wait againTimeout for task 7; wait again Timeout for task 9; wait again Timeout for task 8; wait again Task 5 releases the semaphore Task 7 locks the semaphoreTask 6 releases the semaphore Task 4 releases the semaphore Task 8 locks the semaphore Task 9 locks the semaphoreTask 8 releases the semaphore Task 7 releases the semaphore Task 9 releases the semaphore All tasks finished

标签:again,Task,杏鑫,C#,Semaphore,task,Timeout,semaphore,wait
来源: https://www.cnblogs.com/xingxin666888/p/16124907.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有