[.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 ...
随机推荐
- Extjs Vbox布局方式,以及align种类,flex,pack属性含义简介
VBox布局方式,熟悉下一下几个主要属性: 一.align:字符类型,指示组件在容器内的对齐方式.这个是基于容器的左上角来排列的.pack不同,pack是根据容器的最上边来显示的. 1.left(默认 ...
- HTML 视频(Videos)
前端video做起来很简单,但是还是需要做一些记录,不然下次再做相关的业务仍得费时间找. 参考地址: http://www.jq22.com/jquery-info404 http://www.run ...
- vue2.0 element学习
1,bootstrap和vue2.0结合使用 vue文件搭建好后,引入jquery和bootstrap 我采用的方式为外部引用 在main.js内部直接导入 用vue-cli直接安装jquery和bo ...
- IE8不支持数组的indexOf方法 如何解决
转自:http://www.jbxue.com/article/8367.html 原因分析: 这是一个js bug, 在IE8下,js数组没有indexOf方法,会报错:而在其它浏览器下(Firef ...
- Nginx下SSL证书设置和反向代理
上来就贴代码: server { listen ; server_name **.****.net; #填写绑定证书的域名 ssl on; ssl_certificate /opt/nginx-/co ...
- php用get方式传json数据 变成null了
$data = I('param.data'); $data=stripslashes(html_entity_decode($data));//$data为传过去的json字符串
- Fiddler的钩子hook导致电脑无法连上网络
今天,电脑怎么都无法连上网络,重启了几次电脑也不行,网络环境是没有问题的,后来同事告诉我,Fiddler有一个BUG,就是Fiddler获取钩子之后没有释放掉,必须启动Fiddler,再关闭Fiddl ...
- swift http post json + 登录
var nsUrl : NSURL = NSURL(string:API_HOST+"/"+LOGIN_API)! var request = NSMutableURLReques ...
- Monte carlo
转载 http://blog.sciencenet.cn/blog-324394-292355.html 蒙特卡罗(Monte Carlo)方法,也称为计算机随机模拟方法,是一种基于"随机数 ...
- 643. Maximum Average Subarray I
static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...