zoukankan      html  css  js  c++  java
  • C# Semaphore

    1.Semaphore定义
    Semaphore,是负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。也是操作系统中用于控制进程同步互斥的量。

    Semaphore常用的方法有两个WaitOne()和Release(),Release()的作用是退出信号量并返回前一个计数,而WaitOne()则是阻止当前线程,直到当前线程的WaitHandle 收到信号。这里我举一个例子让大家更容易理解:

    当我们这样实例化Semaphore时候,如果写Semaphore sema = new Semaphore(x,y)这种表达式,就可以理解为这样一个场景

    有一队人排队上洗手间,人就相当于线程,x为还剩余的位置数量,y为总的位置数量。

    WaitOne()方法就相当于人在等待洗手间位置的行为,而Release()方法就相当于一个人从洗手间出来的行为,这里再假设x和y都为5,说明开始的时候洗手间有5个空位置,且总共只有5个位置,当一队超过5个人的队伍要上洗手间的就排队,首先WaitOne()方法等待,发现有空位就依次进去,每进去一个空位减一,直到进去5之后个没有空位,这时候后面的人就一直等待,直到进去的人从洗手间出来Release()方法,空位加一,在等待WaitOne()方法的人发现有空位又进去一个空位减一……如此循环往复。

    2、代码举例

     1 class Program
     2     {
     3         static Semaphore semaphore;
     4         //当前信号量中线程数量
     5         static int count;
     6         //用于生成随机数
     7         static Random r;
     8 
     9         static void Main()
    10         {
    11             r = new Random();
    12             //初始化信号量:初始请求数为1,最大请求数为3
    13             semaphore = new Semaphore(1, 3);
    14             //放出10个线程
    15             for (int i = 0; i < 5; i++)
    16                 ThreadPool.QueueUserWorkItem(doo, i + 1);
    17             Console.ReadKey(true);
    18         }
    19 
    20         static void doo(object arg)
    21         {
    22             int id = (int)arg;
    23             PrintStatus(id, "等待信号量");
    24             //获取一个资源
    25             semaphore.WaitOne();
    26             PrintStatus(id, "获得信号量开始执行");
    27             PrintCount(1);
    28             Thread.Sleep(r.Next(1000));
    29             PrintStatus(id, "退出");
    30             PrintCount(-1);
    31             //释放一个资源
    32             semaphore.Release();
    33 
    34         }
    35 
    36         //输出线程状态
    37         static void PrintStatus(int id, string s)
    38         {
    39             Console.WriteLine("线程{0}:{1}", id, s);
    40         }
    41 
    42         //修改并输出线程数量
    43         static void PrintCount(int add)
    44         {
    45             //在多进程(线程)的操作系统中不能被其它进程(线程)打断的操作就叫原子操作,一个线程在执行其它线程无法抢占。
    46             //对两个 32 位整数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成。
    47             Interlocked.Add(ref count, add);
    48             //以原子操作的形式,将 32 位有符号整数设置为指定的值并返回原始值。
    49             Console.WriteLine("=> 信号量值:{0}", Interlocked.Exchange(ref count, count));
    50         }
    51     }

    参考以下内容:https://www.cnblogs.com/legion/p/6934363.html

    https://blog.csdn.net/yangwohenmai1/article/details/90236036

  • 相关阅读:
    为什么要持续输出
    从Libra看区块链的机遇
    windows 通过choco 安装 .net core windowshosting
    java 正则表达式空格无法匹配
    docker jenkins 安装
    docker jenkins 前端node项目 自动化部署异常 env: ‘node’: No such file or directory
    jenkin docker node 自动化部署配置
    centos docker redis 安装
    Windows server 2012 出现大量无名已断开连接用户清楚办法
    spring boot 打包jar后访问classes文件夹的文件提示地址不存在
  • 原文地址:https://www.cnblogs.com/mojiejushi/p/13221630.html
Copyright © 2011-2022 走看看