Semaphore

msdn介绍:

限制可同时访问某一资源或资源池的线程数。
命名空间: System.Threading
程序集: System(在 System.dll 中)

通俗理解:

1:宾馆开房 房间只能住3个人,现在来了5个人。

2:开门进去3个人 这个时候还有2个人只能在外面等待了。

3:如果出来一个人 剩下的2个进去其中1个。 同理房间还是3个人

后面如果继续来人。 如此往复

核心 总数3个人 。对应msdn 就是允许3个人同时访问 某一资源或资源池的线程数。

构造函数为initialCount和maximumCount,表示默认设置的信号量个数和最大信号量个数,

其实说到底,里面是采用计数器来来分配信号量,

当你WaitOne的时候,信号量自减,

当Release的时候,信号量自增,

然而当信号量为0的时候,后续的线程就不能拿到WaitOne了,所以必须等待先前的线程通过Release来释放。

代码:

namespace ConsoleApplication2
{
class Program
{
static Semaphore sh = new Semaphore(, ); static void Main(string[] args)
{
Thread t1 = new Thread(Run);
t1.Name = "t1"; Thread t2 = new Thread(Run);
t2.Name = "t2"; Thread t3 = new Thread(Run);
t3.Name = "t3"; Thread.Sleep(); t1.Start();
t2.Start(); Thread.Sleep();
t3.Start(); Console.Read();
} static void Run()
{
sh.WaitOne(); Console.WriteLine("大家好,我是{0}", Thread.CurrentThread.Name);
}
}
}

图:

t3 永远都出不来了 原因

static Semaphore sh = new Semaphore(2, 10);

sem.WaitOne(); 就是吧2-- 这里执行2次就变0了

我计数器是2 就是类似上面的房间只能3个人。

10是最大容量 现在进去了2个自然t3出不来了。

这个时候我们手动干预一下,

我们知道调用Release方法相当于自增一个信号量也可以加到maximunCount个信号量 即这里的10

代码:

namespace ConsoleApplication2
{
class Program
{
static Semaphore sh = new Semaphore(, ); static void Main(string[] args)
{
Thread t1 = new Thread(Run);
t1.Name = "t1"; Thread t2 = new Thread(Run);
t2.Name = "t2"; Thread t3 = new Thread(Run);
t3.Name = "t3"; Thread.Sleep(); t1.Start();
t2.Start();
t3.Start(); Thread.Sleep(); sh.Release(); Console.Read();
} static void Run()
{
sh.WaitOne(); if (Thread.CurrentThread.Name == "t3")
{
Console.WriteLine("我终于出来了 我是被sh.Release(10)解放的 我的名字是{0}", Thread.CurrentThread.Name);
}
else
{
Console.WriteLine("大家好,我是{0}", Thread.CurrentThread.Name);
}
}
}
}

Semaphore升级进程交互。

在VS对象浏览器中发现Semaphore是继承字WaitHandle,而WaitHandle封装了win32的一些同步机制,所以当我们给Semaphore命名的时候

就会在系统中可见

namespace System.Threading
{
// 摘要:
// 限制可同时访问某一资源或资源池的线程数。
[ComVisible(false)]
public sealed class Semaphore : WaitHandle
{
.........
}
}

把下面的代码copy一份,运行两个程序。

namespace ConsoleApplication2
{
class Program
{
static Semaphore sh = new Semaphore(, ,"tsp"); static void Main(string[] args)
{
Thread t1 = new Thread(Run);
t1.Name = "t1"; Thread t2 = new Thread(Run);
t2.Name = "t2"; t1.Start();
Thread.Sleep();
t2.Start(); Console.Read();
} static void Run()
{
sh.WaitOne(); Console.WriteLine("当前时间:{0} 大家好,我是{1}", DateTime.Now, Thread.CurrentThread.Name);
}
}
}

t2也出不来了。

Semaphore(信号量)的更多相关文章

  1. CountDownLatch 闭锁、FutureTask、Semaphore信号量、Barrier栅栏

    同步工具类可以是任何一个对象.阻塞队列可以作为同步工具类,其他类型的同步工具类还包括信号量(Semaphore).栅栏(Barrier).以及闭锁(Latch). 所有的同步工具类都包含一些特定的结构 ...

  2. Java并发编程笔记之Semaphore信号量源码分析

    JUC 中 Semaphore 的使用与原理分析,Semaphore 也是 Java 中的一个同步器,与 CountDownLatch 和 CycleBarrier 不同在于它内部的计数器是递增的,那 ...

  3. 互联网进行限流策略的Semaphore信号量使用

    在Semaphore信号量非常适合高并发访问,新系统在上线之前,要对系统的访问量进行评估,当然这个值肯定不是随便拍拍脑袋就能想出来的,是经过以往的经验.数据.历年的访问量,已经推广力度进行一个合理的评 ...

  4. python网络编程--线程Semaphore(信号量)

    一:Semaphore(信号量) 互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才 ...

  5. java并发之(4):Semaphore信号量、CounDownLatch计数锁存器和CyclicBarrier循环栅栏

    简介 java.util.concurrent包是Java 5的一个重大改进,java.util.concurrent包提供了多种线程间同步和通信的机制,比如Executors, Queues, Ti ...

  6. 多线程锁:Mutex互斥体,Semaphore信号量,Monitor监视器,lock,原子操作InterLocked

    Mutex类 “mutex”是术语“互相排斥(mutually exclusive)”的简写形式,也就是互斥量.互斥量跟临界区中提到的Monitor很相似,只有拥有互斥对象的线程才具有访问资源的权限, ...

  7. Python 中Semaphore 信号量对象、Event事件、Condition

    Semaphore 信号量对象 信号量是一个更高级的锁机制.信号量内部有一个计数器而不像锁对象内部有锁标识,而且只有当占用信号量的线程数超过信号量时线程才阻塞.这允许了多个线程可以同时访问相同的代码区 ...

  8. 21.Semaphore信号量

    Semaphore是一种基于计数的信号量.它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞.Semaphore可以用来构建一些对象池,资 ...

  9. java架构之路(多线程)JUC并发编程之Semaphore信号量、CountDownLatch、CyclicBarrier栅栏、Executors线程池

    上期回顾: 上次博客我们主要说了我们juc并发包下面的ReetrantLock的一些简单使用和底层的原理,是如何实现公平锁.非公平锁的.内部的双向链表到底是什么意思,prev和next到底是什么,为什 ...

  10. Python 之并发编程之进程中(守护进程(daemon)、锁(Lock)、Semaphore(信号量))

    五:守护进程 正常情况下,主进程默认等待子进程调用结束之后再结束守护进程在主进程所有代码执行完毕之后,自动终止kill -9 进程号 杀死进程.守护进程的语法:进程对象.daemon = True设置 ...

随机推荐

  1. hdu 4960 Another OCD Patient (最短路 解法

    http://acm.hdu.edu.cn/showproblem.php?pid=4960 2014 Multi-University Training Contest 9 Another OCD ...

  2. JavaScript 学习笔记 -- Function

    JS 中 函数.继承.闭包.作用域链... 一直都是硬伤,一碰到这样的问题头就大了.但是如果我继续着说:我不会,就真的无药可救了.要勇敢地说出:我的字典里就没有不会这个词,吼吼..正好昨天在书城里看了 ...

  3. socket编程报异常java.io.EOFException

    一个客户端连接服务器的小程序,服务器端可以正常读取客户端发来的数据 但是当客户端关闭时,服务端也关闭了,并且抛出如下的异常: java.io.EOFException at java.io.DataI ...

  4. MapReduce的MapTask任务的运行源码级分析

    TaskTracker任务初始化及启动task源码级分析 这篇文章中分析了任务的启动,每个task都会使用一个进程占用一个JVM来执行,org.apache.hadoop.mapred.Child方法 ...

  5. VTK初学一,a Mesh from vtkImageData

    #ifndef INITIAL_OPENGL #define INITIAL_OPENGL #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRend ...

  6. 1、Java背景、标示符、运算符、转义字符

    一.Java平台: 1.Java的创建:1991年由SUN公司创建. 2.Java的特点:面向对象.可移植性.多线程.分布式.可靠.安全. 3.Java的三个架构:JavaEE.JavaSElect. ...

  7. C语言:输入输出

    C语言无I/O语句,i/o操作由函数实现 #include<stdio.h> 字符输出函数putchar: 格式:putchar(c) 参数:c为字符常量,变量或者表达式 功能:把字符c输 ...

  8. 部分LINUX系统由图形界面启动变更为命令行界面启动的方法

    背景: 图形界面很绚丽,但是现在并不需要图形界面,只需要命令行即可,所以要将图形界面自启动给关闭.    正文:   Centos:     更改文件/etc/inittab的其中一行    id:5 ...

  9. 被拒原因——You have selected the Kids Category for your app, but it does not include the required privacy policy. Please update your app metadata to include a privacy policy URL and ensure that the URL yo

    对于一些孩子类的应用,必须加上隐私政策网址(URL),直接截个图吧! 就是你上架的时候,填写应用信息,里面有一个隐私政策网址(URL),望后者不掉坑里了!!!

  10. window使用qt遇到的坑

    1.window上的qt对图片的检测与识别不够完善.往往改了一个ui的背景图片,运行出来显示的却是旧的背景图片. 原因:  由于之前是项目与项目之间整合在一起,然后把ui_*_ui.h的临时文件也放在 ...