C#线程同步(5)- 信号量 Semaphore
文章原始出处 http://xxinside.blogbus.com/logs/47617134.html
预备知识:C#线程同步(1)- 临界区&Lock,C#线程同步(2)- 临界区&Monitor,C#线程同步(3)- 互斥量 Mutex,C#线程同步(4)- 通知&EventWaitHandle一家
这次终于不用说太多话了,某人看这一系列博客的反应总是“好长……”,以至于都不愿意看下去。在这一系列开篇之前,本想应该一、两个星期就能解决,结果每篇总要花上一星期左右。总想把涉及的所有方面都讲得尽量清楚明白,希望容易被看懂。于是总是不断陷于考虑如何串联各处的关系、要写个怎样的例子、细细考量MSDN的每一句话是否妥当……能做的无用的事情也就这点儿,所以还是努力地督促着自己要尽快完成。
呵呵,还是回到正题。信号量也算是个鼎鼎大名的东西吧,提到互斥量总会说起信号量。二者的差别很简单,互斥量、临界区是用于保护“一个”需要被互斥访问的资源,这个资源同时只有一个线程能被访问;而信号量可以被用于管理“资源池”。在.Net中Semaphore类就是对Windows信号量的封装。
跟谁更亲,Mutex还是EventWaitHandle?
本系列的第3篇Mutex、第4篇EventWaitHandle都提到过Semaphore,因为它们同继承于WaitHandle。所以Semaphore必然有着一些我们已经知道的特性:
- 你可以创建没有名称的“局部”信号量,也可以创建命名的“全局”信号量用于跨应用程序域的同步。
- 你可以用WaitOne()请求一个资源。
- 你需要使用try/finally结构调用“Close()”,确保信号量资源在使用后被正确释放。
- 你仍然需要注意在全局情况下Semaphore的访问安全问题。
总的来说,Semaphore与Mutex更像是兄弟,仍然与EventWaitHandle一脉不太亲近:
- Semaphore从机制上来说跟Mutex一样属于“锁”而不是“通知”,因此跟Mutex一样几乎没有“通知”的能力。
- 举个不恰当但是很形象的例子,Semaphore就是一个可以多次进入的“Mutex”。Mutex永远只允许一个线程拥有它,而Semaphore可以允许多个线程请求,因此Semaphore被用于管理一次可以允许多个线程进入并发访问资源的情况。之所以说“不恰当”,是因为一旦允许多个线程访问资源,那么这时候的资源一定不是互斥资源,相应的代码段也不再是“临界区”。你千万不要以为我们在上一篇中提到的“糖罐”里有多颗糖就叫做“资源池”(都说过了嘛一个糖罐一定是需要互斥访问的),除非你有多个糖罐而不是多颗糖。
- 因为Semaphore与Mutex在请求数量上的不同,因此他们的线程相关性是不同的。这一点,Semaphore到跟EventWaitHandle一样,它是线程无关的。也就是说对Semaphore地释放者可以不定是Semaphore的拥有者。比如说我可以是消费者线程总使用WaitOne()请求线程池中的资源从来不需要释放,而生产者总是Release线程池中的资源而从来不请求。
Semaphore的使用方法
如果你已经读过这个系列前面4篇的博文,我想到此为止你已经对Semapore的来龙去脉、性格特点掌握得八九不离十了。就像开篇所说,这次我们我们不要再废很多话来讨论它,大致应该知道的细节,除了上面我们说的差异,都已经在之前各篇讲过了。
所以我决定要偷懒了:
- Semaphore的构造函数在 这里,是的你会觉得已经很熟悉了,一望而知其意。其它的,请仍然记得命名前缀的问题;记得名称仍然是大小写敏感的;最后别忘记使用SemaphoreSecurity类来管理命名信号量的安全。
- Semaphore仍然使用WaitOne()请求资源,接口都来自WaitHandle,你已经看过很多遍了。
- Semaphore使用Release()来表示对资源的释放,不过与ReleaseMutex()不同,这个函数有重载方法允许你指定释放几个资源。这引发了一个问题,如果Release的次数超过资源总量,那么会引发SemaphoreFullException异常。比如线程A和线程B都进入信号量。如果线程B中发生了一个编程错误,导致它调用Release()两次(或者Release(2)),则两次调用都会成功。这样,信号量的计数就已经达到了最大值,所以,当线程A最终调用Release时将引发异常。这相当于本来资源中只有N个资源,最后却有超过N个资源被还回来。
- 记得使用完以后调用Close()释放信号量资源。
Sample Code
嘿嘿,没有。因为我实在想不出有什么特别适合Sempore的简单例子,总不能把Mutex那个应用程序单例的例子改成允许启动指定个数吧。等想到了,再来补上吧。就请先参见MSDN上的相关示例代码吧。
C#线程同步(5)- 信号量 Semaphore的更多相关文章
- [b0032] python 归纳 (十七)_线程同步_信号量Semaphore
代码: # -*- coding: utf-8 -*- """ 多线程并发同步 ,使用信号量threading.Semaphore 逻辑: 多个线程,对同一个共享变量 , ...
- 线程同步 –Mutex和Semaphore
上一篇介绍了同步事件EventWaitHandle,以及它的两个子类型AutoResetEvent和ManualResetEvent.下面接着介绍WaitHandle的另外两个子类型Mutex和Sem ...
- Python并行编程(五):线程同步之信号量
1.基本概念 信号量是由操作系统管理的一种抽象数据类型,用于在多线程中同步对共享资源的使用.本质上说,信号量是一个内部数据,用于标明当前的共享资源可以有多少并发读取. 同样在threading中,信号 ...
- 线程同步、信号量、system v IPC
一.线程同步 条件变量 什么是条件变量? 线程A等待某个条件成立,条件成立,线程A才继续向下执行.线程B的执行使条件成立,条件成立以后唤醒线程A,以继续执行.这个条件就是条件变量. pthread_c ...
- 线程同步之信号量(sem_init,sem_post,sem_wait)
信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区. 不多做解释,要使用信号量同步,需要包含头文件semaphore.h. 主要用到的函数: int ...
- [b0040] python 归纳 (二五)_多进程数据共享和同步_信号量Semaphore
# -*- coding: utf-8 -*- """ 多进程同步 使用信号量 multiprocessing.Semaphore 逻辑: 启动5个进程,打印,每个各自睡 ...
- Python 线程同步锁, 信号量
同步锁 import time, threading def addNum(): global num num -= 1 num = 100 thread_list = [] for i in ran ...
- JDK5.0 特性-线程同步装置之Semaphore
来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291474.html import java.util.ArrayList; import j ...
- c++线程同步之信号量
// MutexExDlg.h : 头文件 // #pragma once // CMutexExDlg 对话框 class CMutexExDlg : public CDialogEx { // 构 ...
- Java多线程—线程同步(单信号量互斥)
JDK中Thread.State类的几种状态 线程的生命周期 线程的安全问题(同步与互斥) 方法一:同步代码块 多个线程的同步监视器(锁)必须的是同一把,任何一个类的对象都可以 syn ...
随机推荐
- Centos7双网卡绑定配置 bonding
bonding的七种工作模式: bonding技术提供了七种工作模式,在使用的时候需要指定,每种有各自的优缺点,我们使用的是 mode=4 balance-rr (mode=0) 默认, 有高可用 ( ...
- 必备Linux命令和C语言基础
每一个学习嵌入式单片机的伙伴我相信对于这两个都不陌生,这毕竟是嵌入式单片机的生存之道 所有基础还是要打牢的 有句老话说的好基础不牢地动山摇 下面看下系统的资料吧 希望能对大家有所帮 ...
- 分析一个MySQL并发事务示例
小结: 1. https://mp.weixin.qq.com/s/hdDl95a6ayVtCoEc3RiLwQ 分析一个MySQL并发事务示例 性能与架构 1月12日 MySQL实战45讲 从原 ...
- Dear ImGUI 使用指南
文档 1)Dear IMGui 2) 知乎 组件 1) Com 如何设置动态字符串? //char*pTest = "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0&quo ...
- 爬虫-----selenium模块自动爬取网页资源
selenium介绍与使用 1 selenium介绍 什么是selenium?selenium是Python的一个第三方库,对外提供的接口可以操作浏览器,然后让浏览器完成自动化的操作. sel ...
- linux /proc/sys/vm/中各个文件含义
1) /proc/sys/vm/block_dump该文件表示是否打开Block Debug模式,用于记录所有的读写及Dirty Block写回动作. 缺省设置:0,禁用Block Debu ...
- 使用纳米 Protocol buffers 作为序列化数据
使用纳米 Protocol buffers 作为序列化数据 Protocol Buffers 是 Google 公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化. 但是它更小, 更快, ...
- UGUI中UI与模型混合显示
法一: 利用Render Texture 在project面板创建 在面板中在创建一个Camera,对准要显示的模型 对Render Texture 进行设置 在Canvas下创建RawImage 就 ...
- git冲突管理
Diff 查看工作区(working directory)和暂存区(staged)之间差异:git diff 查看工作区(working directory)与当前仓库版本(repository)HE ...
- 记录心得-FastJson分层解析demo示例
记录一下,平时用到,可速查!关键: // startArray(); 开始解析数组 // endArray(); 结束解析数组 // startObject(); 开始解析键值对 // endObje ...