C# Semaphore 信号量 锁 简单理解
信号量(Semaphore)
Semaphore 一般译作 信号量
,它也是一种线程同步工具,主要用于多个线程对共享资源进行并行操作的一种工具类。它代表了一种许可
的概念,是否允许多线程对同一资源进行操作的许可,使用 Semaphore 可以控制并发访问资源的线程个数。
Semaphore 的使用场景
它与的互斥锁区别是 互斥锁:是线程间互斥用的,一个线程占用了某一个共享资源,那么别的线程就无法访问,直到这个线程离开,其他的线程才开始可以使用这个共享资源。可以把互斥锁看成二值信号量。
引发的问题
优先级反转,是指在使用信号量时,可能会出现的这样一种不合理的现象,即:
高优先级任务被低优先级任务阻塞,导致高优先级任务迟迟得不到调度。但其他中等优先级的任务却能抢到CPU资源。-- 从现象上来看,好像是中优先级的任务比高优先级任务具有更高的优先权。
具体来说:当高优先级任务正等待信号量(此信号量被一个低优先级任务拥有着)的时候,一个介于两个任务优先之间的中等优先级任务开始执行——这就会导致一个高优先级任务在等待一个低优先级任务,而低优先级任务却无法执行类似死锁的情形发生。
主要方法
Semaphore(1, 4):默认运行信号量之后就可以释放一条线程进入临界资源。手动设置Release的一次最大个数是4条线程,临界区最大的线程数是4.当一次释放的线程超过等待的资源数就会报错
WaitOne()阻塞线程,等灯来
Release(N) 同时放行条线程进入资源区,最大不能超过初始化设定的maximumCount
Close()释放所有
使用方式1
有10个线程,同时只执行4条线程,每完成一个就Release一个,等待中的就补上去
代码如下:
该代码会正常执行完成,并且释放所有线程,因为初始化话new Semaphore(1, 4)时候已经设置默认释放一条线程,这条线程执行完成后road.Release();又释放下一条。依次释放完所有线程。
Semaphore road = new Semaphore(1, 4);
for(int i = 0; i < 10; i++)
{
new Thread(obj =>
{
int se = (int)obj;
Console.WriteLine(se);
road.WaitOne(); Console.WriteLine("release{0}",obj);
road.Release();//该线程执行完毕,后再释放一个线程
} ).Start(i); }
Thread.Sleep(1000);
//该代码会正常执行完成,并且释放说有线程,因为初始化话new Semaphore(1, 4)时候已经设置默认释放一条线程,这条线程执行完成后road.Release();又释放下一条。依次释放完所有线程。
另外,信号量是内核对象可以再多个进程中使用。可以给信号量设置一个名称,这个名称是操作系统可见的,因此,可以使用这些信号量来协调跨进程边界的资源使用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; namespace Semaphore2
{
class Program
{
static void Main(string[] args)
{
Semaphore seamphore = new Semaphore(5, 5, "SemaphoreExample"); seamphore.WaitOne();
Console.WriteLine("Seamphore 1");
seamphore.WaitOne();
Console.WriteLine("Seamphore 2");
seamphore.WaitOne();
Console.WriteLine("Seamphore 3"); Console.ReadLine();
seamphore.Release(3);
}
}
} 复制代码
运行两个这样的程序,你将看到这样的结果,在第二个运行的示例中,会将线程阻塞在第三个信号量
最新文章
- Fresco从配置到使用(最高效的图片加载框架)
- logrotate机制与原理[转载]
- 【转载】阎焱:90后创业是扯淡 大量O2O和P2P公司濒临倒闭
- C#事件快捷设置
- 什么是RFC
- 基于C++/Lua的游戏服务器如何实现?
- 【原】visual studio添加现有文件夹的方法
- .Net 接连 Oracle 数据库(Winform)
- 关于a[i]++和a[i++]说明
- 搭建环境-Monkeyrunner-自动化测试工具
- Redis数据结构之ziplist
- MySQL使用root权限创建用户并授权
- MySQL设置global变量和session变量
- ubuntu系统安装微信小程序开发工具
- OpenGL初学:安装配置与第一个程序
- “数学口袋精灵”App的第三个Sprint计划(总结与团队感悟)----开发日记
- ThinkPHP中如何获取指定日期后工作日的具体日期
- 雷林鹏分享:XML 相关技术
- Windows编译Opencv
- phpstorm——配置interpreter——找了半天终于ok