[.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 ...
随机推荐
- 53. Maximum Subarray最大求和子数组12 3(dp)
[抄题]: Find the contiguous subarray within an array (containing at least one number) which has the la ...
- VMware安装centos虚拟机 通过NAT与主机互通并能上网
1.关于centos虚拟机的安装,我这里就不详细说明了,网上有很多教程,默认你们已经安装好. (我的环境是centos6.6 x86 最小安装版) 2.右键虚拟主机,选择设置选项. 3.在 ...
- JSP标准标签库JSTL
1.什么是JSTL? JSP标准标签库(JSP Standard Tag Library) 2.JSTL标准标签库中的常用标签 JSTL是JSP页面的标签库,实质上是一段Java代码.我们常用的是它的 ...
- struts框架问题五之向值栈中保存数据
5. 问题五: 向值栈保存数据 (主要针对root栈) > valueStack.push(Object obj); * push方法的底层调用root对象的push方法(把元素添加到0位置) ...
- Tornado异步阻塞解决方案
在 tornado 中异步无阻塞的执行耗时任务 在 linux 上 tornado 是基于 epoll 的事件驱动框架,在网络事件上是无阻塞的.但是因为 tornado 自身是单线程的,所以如果我们在 ...
- BZOJ1222 [HNOI2001]产品加工 - 动态规划- 背包
题解 怎么看都不像是个背包,直到我看了题解→_→, 第一次碰到这么奇怪的背包= = 定一个滚动数组$F_i$, $i$表示机器$a$用了$i$的时间, $F_i$表示机器$b$用了$F_i$的时间, ...
- 别人家的PS系列又来了!!!
又到了“别人的PS”系列的日常感叹了,大家请边看推文边组织语言准备留言,用点新鲜词,不要再说什么给跪了,献上膝盖之类的,争取换点词. 好了,废话不多说,开始正文,先看几则简单的PS作品: 这两组作品出 ...
- Java 8 Stream API
Java 8 Stream API JDK8 中有两大最为重要的改变.第一个是 Lambda 式:另外 Stream API(java.util.stream.*) Stream 是 JDK8 中处理 ...
- 学习Java的方法
许多人在刚开始学习Java时,会因为学习方法的不正确,而丧失信心,从而半途而废.所以,今天,巩固就要教教大家学习Java的方法. 1.多练习 编程其实是一个非常抽象的东西,要想学好它,就不能只是看看书 ...
- Determine overlapping rectangles
https://github.com/Premiumlab/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/Moc ...