百度百科: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. sCMOS相机调试参考资料

    sCMOS相机调试参考资料 实验室调试sCMOS传感器,特此记录一下网上搜集的资料. 来自比利时的AXIOM开源相机公司:https://wiki.apertus.org/index.php/Sens ...

  2. python函数与模块(装饰器,文件处理,迭代器等)

    os模块 os.system('命令') 利用python调用系统命令,命令可以是以列表或者元组内的元素形式* res import os res=os.system('ipconfig') prin ...

  3. day44前端开发2之css基础

    web前端开发1一.前端三剑客之css 1.选择器:由标签/类/id单独或组合出现 2.作用域:{}内部区域 3.样式块:满足css链接语法的各种样式 eg:引入的基本样式 <head>  ...

  4. MYSQL数据库中中文乱码问题

    show variables like 'character%'; set character_set_database=gbk; 把记事本中的代码引入到mysql数据库中:source +addre ...

  5. Python Queue(队列)

    Queue模块实现了多生产者.多消费者队列.当必须在多个线程之间安全地交换信息时,它在线程编程中特别有用,实现了所有必需的锁定语义. 一.该模块实现了三种类型的队列,它们的区别仅在于检索条目的顺序: ...

  6. sql注入、csrf

    ◎sql注入产生的原因?又如何防御sql注入? SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用 ...

  7. C#创建windows服务并发布

    创建window 服务 新建一个window 服务项目MyService,如下图 切换到代码视图修改. using System; using System.Collections.Generic; ...

  8. uva-757-贪心

    题意:有个人要去湖里钓鱼,总共有N个湖,排成一个序列,用字母P表示湖,从湖pi 到 pi+1(下一个湖)需要ti个五分钟. 并且,每个湖里可钓出来的鱼每过五分钟就减少di.如果产出的鱼小于等于di.那 ...

  9. C++builder Tokyo 调用com 不正确的变量类型

    C++builder Tokyo 调用com 不正确的变量类型 tt.OleFunction("interface_call","MS01",&erro ...

  10. The type initializer for System.Data.SqlClient.SqlConnection threw an exception

    The type initializer for System.Data.SqlClient.SqlConnection threw an exception net framwork啥原因 xp电脑