[.net]基元线程同步构造
/* 基元线程同步构造
用户模式构造:
易变构造(Volatile Construct)
互锁构造(Interlocked Construct):自旋锁(Spinlock) 乐观锁(Optimistic Concurrency Control,乐观并发控制)
内核模式构造:
事件构造(Event)
信号量构造(Semaphore)
互斥体构造(Mutex)
*/ //易变构造,Volatile.Write()之前的所有字段写入操作,必须再该方法调用之前完成,Volatile.Read()之前的所有字段读取操作,必须再该方法之前完成,保证该方法作用的字段
//的赋值或读取顺序不被编译器优化,C#关键字volatile在语言层面提供了对易变构造的支持,标记为volatile的字段在按引用传递时无效。
public static class Volatile
{
public static void Write(ref Int32 location,Int32 value);
public static Int32 Read(ref Int32 location);
} //互锁构造
public static class Interlocked
{
public static Int32 Exchange(ref Int32 location,Int32 value); //Int32 old=location; if(location==comparand){ location=comparand;} return old;
public static Int32 CompareExchange(ref Int32 location,Int32 value,Int32 comparand);
} //简单自旋锁:自旋会浪费CPU时间,因此自旋锁只适用于执行的非常快的代码区域。在单CPU计算机上,希望获得锁的线程会不断的自旋,如果获得锁的线程优先级比较低的话,
//会导致自旋的线程抢占CPU时间,从而影响拥有锁的线程释放锁,比较容易形成“活锁”。
public struct SimpleSpinlock
{
private Int32 _inUse;//0:false,1:true,Interlocked不支持Boolean
public void Enter()
{
while (true)
{
if(Interlocked.Exchange(ref _inUse,)==)
return;
//一些其他代码
}
}
public void Leave()
{
Volatile.Write(ref _inUse,);
}
}
public class Demo
{
private SimpleSpinlock _spinLock;
public void Access()
{
_spinLock.Enter();
//取得锁,访问资源
_spinLock.Leave();
}
} //欢乐锁:用于完成一次原子性的操作,如果在执行过程中,数据被外部修改,那么当前执行的过程就无效,然后用修改后的值重新进行这次原子性的操作。
//说直白点就是乐观,与世无争。
public class OptimisticLoack
{
public delegate T Morpher<T, TArgument>(T startValue, TArgument argument);
public static T Morph<T, TArgument>(ref T target, TArgument value, Morpher<T,TArgument> morpher)where T:class
{
T currentValue = target, startValue, desiredValue;
do
{
startValue = currentValue;
desiredValue = morpher(startValue, value);
currentValue = Interlocked.CompareExchange(ref target, desiredValue, startValue);
} while (currentValue != startValue);
return desiredValue;
}
} //事件构造:自动重置事件 手动重置事件
public class EventWaitHandle:WaitHandle
{
public Boolean Set();
public Boolean Reset();
}
public class AutoResetEvent():EventWaitHandle
{
public AutoResetEvent(Boolean initialState);
}
public class ManualResetEvent():EventWaitHandle
{
public ManualResetEvent(Boolean initialState);
} //信号量构造
public class Semaphore:WaitHandle
{
public Semaphore(Int32 initialCount,Int32 maxinumCount);
public Int32 Release();
public Int32 Release(Int32 releaseCount);
} //互斥体构造,内部维护一个递归计数,可以实现递归锁
public sealed class Mutex:WaitHandle
{
public Mutex ();
public void ReleaseMutex();
} //事件构造,信号量构造,互斥体构造均可以简单的实现自旋锁
public class SimpleSpinlock
{
private readonly Mutex m_lock=new Mutex();//针对互斥体构造
//private readonly Semaphore m_lock=new Semaphore();//针对信号量构造
//private readonly AutoResetEvent m_lock=new AutoResetEvent(true);//针对事件构造
public void Enter()
{
m_lock.WaitOne();
}
public void Leave()
{
m_lock.ReleaseMutex();//针对互斥体构造
//m_lock.Release(1);//针对信号量构造
//m_lock.Set();//针对事件构造
}
}
[.net]基元线程同步构造的更多相关文章
- 基元线程同步构造之waithandle中 waitone使用
在使用基元线程同步构造中waithandle中waitone方法的讲解: 调用waithandle的waitone方法阻止当前线程(提前是其状态为Nonsignaled,即红灯),直到当前的 Wait ...
- 【C#进阶系列】28 基元线程同步构造
多个线程同时访问共享数据时,线程同步能防止数据损坏.之所以要强调同时,是因为线程同步问题实际上就是计时问题. 不需要线程同步是最理想的情况,因为线程同步一般很繁琐,涉及到线程同步锁的获取和释放,容易遗 ...
- Clr Via C#读书笔记----基元线程同步构造
线程文章:http://www.cnblogs.com/edisonchou/p/4848131.html 重点在于多个线程同时访问,保持线程的同步. 线程同步的问题: 1,线程同步比较繁琐,而且容易 ...
- 基元线程同步构造之 Mutes(互斥体)
互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)). 互斥体禁止多个线程同时进入受保护的代码“临界区”(critical section). 因 ...
- 基元线程同步构造 AutoResetEvent和ManualResetEvent 线程同步
在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似,但也有区别.ManualResetEvent和AutoResetEvent都 ...
- CLR via C# I/O基元线程同步构造
1. 分为用户模式构造和内核模式构造 2. 用户模式构造 a.易失构造 在一个简单数据类型的变量上执行原子性读或写操作 VolaileWrite 强制address中的值在调用时写入,除此之外,按照源 ...
- 基元线程同步构造之信号量(Semaphore)
信号量(semaphore)不过是由内核维护的 int32变量而已,(说通俗点就是好比一个线程容器里面允许执行的线程数,0计数就是允许执行的0个线程数,1就是允许执行的1个线程数,2就是允许执行的2个 ...
- 【C#进阶系列】29 混合线程同步构造
上一章讲了基元线程同步构造,而其它的线程同步构造都是基于这些基元线程同步构造的,并且一般都合并了用户模式和内核模式构造,我们称之为混合线程同步构造. 在没有线程竞争时,混合线程提供了基于用户模式构造所 ...
- 【C#】C#线程_基元线程的同步构造
目录结构: contents structure [+] 简介 为什么需要使用线程同步 线程同步的缺点 基元线程同步 什么是基元线程 基元用户模式构造和内核模式构造的比较 用户模式构造 易变构造(Vo ...
随机推荐
- 硬盘的 read0 read 1
Read 0:组建的时候必须2块容量相同的硬盘,每个程序的数据以一定的大小分别写在两个硬盘里,读的时候从两个硬盘里一起读,这种阵列方式理论上硬盘的读写速度是一块硬盘的2倍,实际应用中大约速度比一块硬盘 ...
- uploadify 文件上传报http 302错误
uploadify文件上传会报http 302错误,在配置文件中将处理上传的通用类取消验证, 假设上传的通用处理类是fileUpload.ashx,则在配置文件同添加下面过滤配置能解决问题. < ...
- Spring整合Struts2框架的第一种方式(Action由Struts2框架来创建)。在我的上一篇博文中介绍的通过web工厂的方式获取servcie的方法因为太麻烦,所以开发的时候不会使用。
1. spring整合struts的基本操作见我的上一篇博文:https://www.cnblogs.com/wyhluckdog/p/10140588.html,这里面将spring与struts2 ...
- 搭建Eureka集群
1.pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- Ubuntu的人性化配置
1.更改Ubuntu命令行提示符颜色,在~/.bashrc中添加如下命令行: PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[ ...
- windows驱动
DriveEntry() 启动 停止 接口函数 驱动程序名 驱动程序版本号 异常处理 是否运行 声明LPOReceive类型的函数 声明函数指针(外部传进来的回调函数) 存放配置字符串 本机IP 串口 ...
- Django入门指南-第10章:Django Admin 介绍(完结)
在浏览器中打开该URL:http://127.0.0.1:8000/admin/ 我们可以检查一切是否正常,打开URL http://127.0.0.1:8000 我们首先创建一个管理员帐户: pyt ...
- Django入门与实践-第22章:基于类的视图
http://127.0.0.1:8000/boards/1/topics/2/posts/2/edit/ http://127.0.0.1:8000/ #boards/views.py from d ...
- Django入门与实践-第19章:主题回复(完结)
http://127.0.0.1:8000/boards/1/topics/1/reply/ http://127.0.0.1:8000/boards/1/topics/1/ #myproject/u ...
- js正则表达式汇集
1.只允许中文.字母.数字.中划线.下划线.空格.中文的().英文的()和#,只能以数字.中文.字母.下划线开头,长度为2至40之间 validateTemplateName: function(va ...