百度百科: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()方法的人发现有空位又进去一个空位减一……如此循环往复。

请看下面例子:

public class Program
{
static Semaphore sema = new Semaphore(5, 5);
const int cycleNum = 9;
static void Main(string[] args)
{
for(int i = 0; i < cycleNum; i++)
{
Thread td = new Thread(new ParameterizedThreadStart(testFun));
td.Name = string.Format("编号{0}",i.ToString());
td.Start(td.Name);
}
Console.ReadKey();
}
public static void testFun(object obj)
{
sema.WaitOne();
Console.WriteLine(obj.ToString() + "进洗手间:" + DateTime.Now.ToString());
Thread.Sleep(2000);
Console.WriteLine(obj.ToString() + "出洗手间:" + DateTime.Now.ToString());
sema.Release();
}
}

运行结果如下:

这里我要说明一点,信号量控制的只是线程同步的量,而不管顺序,这个例子来说线程控制的就是线程同步量为5,也就是同时并发的线程数量为5个,至于是哪个先哪个后不是由这里的信号量决定的。

当然这个例子中因没有做什么复杂的操作,一般情况进入线程的时间和每个线程要的时间不会有太大差别,所以执行的顺序还是很规律的(为了说明这个问题我也是运行了多次才让结果稍有不同,这里编号2抢在了编号1前面就是这个道理),如果线程中有很复杂的操作每个线程在运行中所用的时间有比较大的差别,或者循环开始有复杂操作那么很可能就不是编号0先进入洗手间了,且不一定是先进入的就会先出来。

接下来再简单介绍一下Semaphore的WaitOne()和Release()的重载方法

public int Release(int releaseCount);

releaseCount指的是释放的信号量数量,如果没有参数默认为1,Release()就相当于Release(1)

这里要说明一点,当Release()或者Release(int releaseCount)执行时导致信号量计数大于最大数量时会抛出SemaphoreFullException异常。下面这种情况就会异常:

Semaphore sem = new Semaphore(4,5);
sem.Release(2);//这里是释放2个信号量加上之前的4个,超出5个了
public virtual bool WaitOne(TimeSpan timeout);
public virtual bool WaitOne(int millisecondsTimeout);

第一个重载参数timeout:指定时间间隔,若在这段时间内没有接收到信号则跳过等待继续执行

第二个重载参数millisecondsTimeout:指定时间间隔整数毫秒,若在这段时间内没有接收到信号则跳过等待继续执行

WaitOne()还有两个重载方法不是很常用这里就不介绍了。上面的重载方法这里也不再进了案例说明了,有兴趣的朋友可以自己尝试一下。

C#多线程--信号量(Semaphore)[z]的更多相关文章

  1. 多线程信号量 Semaphore使用

    对信号量只能实施三种操作:  1. 初始化(initialize),也叫做建立(create)  2. 等信号(wait),也可叫做挂起(pend)  3. 给信号(signal)或发信号(post) ...

  2. java多线程--信号量Semaphore的使用

    Semaphore可以控制某个共享资源可被同时访问的次数,即可以维护当前访问某一共享资源的线程个数,并提供了同步机制.例如控制某一个文件允许的并发访问的数量. 例如网吧里有100台机器,那么最多只能提 ...

  3. 多线程-信号量Semaphore

    计数信号量用来控制同时访问某个特定资源的操作数量.Semaphore可以用于实现资源池,例如数据库连接池.我们可以构造一个固定长度的资源池,当资源池为空的时候,请求资源将会阻塞,而不是失败.当资源池非 ...

  4. C#多线程--信号量(Semaphore)

    百度百科:Semaphore,是负责协调各个线程, 以保证它们能够正确.合理的使用公共资源.也是操作系统中用于控制进程同步互斥的量. Semaphore常用的方法有两个WaitOne()和Releas ...

  5. 秒杀多线程第八篇 经典线程同步 信号量Semaphore

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <且不超过最大资源数量. 第三个參数能够用来传出先前的资源计数,设为NULL表示不须要传出. 注意:当 ...

  6. 多线程面试题系列(8):经典线程同步 信号量Semaphore

    前面介绍了关键段CS.事件Event.互斥量Mutex在经典线程同步问题中的使用.本篇介绍用信号量Semaphore来解决这个问题. 首先也来看看如何使用信号量,信号量Semaphore常用有三个函数 ...

  7. 转---秒杀多线程第八篇 经典线程同步 信号量Semaphore

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  8. Java多线程-新特征-信号量Semaphore

    简介信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确.合理的使用公共资源. 概念Semaphore分为单值和多值两种,前者只能 ...

  9. 并发编程~~~多线程~~~守护线程, 互斥锁, 死锁现象与递归锁, 信号量 (Semaphore), GIL全局解释器锁

    一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') ...

  10. Java基础教程:多线程基础(6)——信号量(Semaphore)

    Java基础教程:多线程基础(6)——信号量(Semaphore) 信号量 信号量(Semaphore)由一个值和一个指针组成,指针指向等待该信号量的进程.信号量的值表示相应资源的使用情况.信号量S≥ ...

随机推荐

  1. spring静态注入

    与其说是静态注入(IOC),不如讲是对JavaBean 的静态成员变量进行赋值. 一般我们在使用依赖注入的时候,如果当前对象(javaBean )创建(实例化)一次,那么非静态的成员变量也会实例化一次 ...

  2. python3 数独

    数独 最近在网上看到数独,感觉非常有意思,所以就来实现以下. 一个数独题的网站(https://www.oubk.com/DailySudoku/17778/1),偷懒直接爬虫抓下来了,哈哈 代码实现 ...

  3. LBP特征学习(附python实现)

    LBP的全称是Local Binary Pattern即局部二值模式,是局部信息提取中的一种方法,它具有旋转不变性和灰度不变性等显著的优点.在人脸识别领域有很多案例,此外,局部特征的算法还有 SIFT ...

  4. 位运算骚操作 Part 3

    ▶ 异或运算 "^" 具有的部分性质: ● 交换律,结合律 ● a ^ b == (!a & b) | (a & !b),a ^ 1 == !a,a ^ 0 == ...

  5. FPGA笔试必会知识点1--数字电路基本知识

    组合逻辑与时序逻辑 组合逻辑电路:任意时刻电路输出的逻辑状态仅仅取决于当时输入的逻辑状态,而与电路过去的工作状态无关. 时序逻辑电路:任意时刻电路输出的逻辑状态不仅取决于当时输入的逻辑状态,而与电路过 ...

  6. 11Linux_sshd_Apache

    1.Linux系统中一切都是文件. 2.配置服务实际上就是在修改配置文件. 3.重启相应服务来加载最新的配置参数. 4.为了保证下次还生效,加入到开机启动项中.

  7. sql server 新语法 收藏

    1.行转列 PIVOT函数,行转列,列转换UNPIVOT select * from ShoppingCart as C PIVOT(count(TotalPrice) FOR [Week] IN([ ...

  8. MM-分割评估

    SAP MM分割评估 https://blog.csdn.net/kangliujie/article/details/76681333 SAP MM批次管理分割评估 https://blog.csd ...

  9. window Linux 双系统安装

    我是先安装的win10,然后在其基础上又安装了Ubuntu 16.04,为了今后再次安装方便,这里记录一下安装过程. 我在安装时主要参考了文章:https://blog.csdn.net/flyyuf ...

  10. NSIS 查找目录下的所有文件夹

    在制作安装包的时候,需要查看下某一目录下的所有文件夹的名称.经过查资料发现需要用到NSIS 的一个插件Locate.下载该插件后,会在NSIS的安装目录 ...Program Files\NSIS\P ...