[.net]基元线程同步构造

  1 /* 基元线程同步构造
  2 用户模式构造:
  3     易变构造(Volatile Construct)
  4     互锁构造(Interlocked Construct):自旋锁(Spinlock) 乐观锁(Optimistic Concurrency Control,乐观并发控制)
  5 内核模式构造:
  6     事件构造(Event)
  7     信号量构造(Semaphore)
  8     互斥体构造(Mutex)
  9 */
 10
 11 //易变构造,Volatile.Write()之前的所有字段写入操作,必须再该方法调用之前完成,Volatile.Read()之前的所有字段读取操作,必须再该方法之前完成,保证该方法作用的字段
 12 //的赋值或读取顺序不被编译器优化,C#关键字volatile在语言层面提供了对易变构造的支持,标记为volatile的字段在按引用传递时无效。
 13 public static class Volatile
 14 {
 15     public static void Write(ref Int32 location,Int32 value);
 16     public static Int32 Read(ref Int32 location);
 17 }
 18
 19 //互锁构造
 20 public static class Interlocked
 21 {
 22     public static Int32 Exchange(ref Int32 location,Int32 value);
 23
 24     //Int32 old=location; if(location==comparand){ location=comparand;} return old;
 25     public static Int32 CompareExchange(ref Int32 location,Int32 value,Int32 comparand);
 26 }
 27
 28 //简单自旋锁:自旋会浪费CPU时间,因此自旋锁只适用于执行的非常快的代码区域。在单CPU计算机上,希望获得锁的线程会不断的自旋,如果获得锁的线程优先级比较低的话,
 29 //会导致自旋的线程抢占CPU时间,从而影响拥有锁的线程释放锁,比较容易形成“活锁”。
 30 public struct SimpleSpinlock
 31 {
 32     private Int32 _inUse;//0:false,1:true,Interlocked不支持Boolean
 33     public void Enter()
 34     {
 35         while (true)
 36         {
 37             if(Interlocked.Exchange(ref _inUse,1)==0)
 38                 return;
 39             //一些其他代码
 40         }
 41     }
 42     public void Leave()
 43     {
 44         Volatile.Write(ref _inUse,0);
 45     }
 46 }
 47 public class Demo
 48 {
 49     private SimpleSpinlock _spinLock;
 50     public void Access()
 51     {
 52         _spinLock.Enter();
 53         //取得锁,访问资源
 54         _spinLock.Leave();
 55     }
 56 }
 57
 58
 59 //欢乐锁:用于完成一次原子性的操作,如果在执行过程中,数据被外部修改,那么当前执行的过程就无效,然后用修改后的值重新进行这次原子性的操作。
 60 //说直白点就是乐观,与世无争。
 61 public class OptimisticLoack
 62 {
 63     public delegate T Morpher<T, TArgument>(T startValue, TArgument argument);
 64     public static T Morph<T, TArgument>(ref T target, TArgument value, Morpher<T,TArgument> morpher)where T:class
 65     {
 66         T currentValue = target, startValue, desiredValue;
 67         do
 68         {
 69             startValue = currentValue;
 70             desiredValue = morpher(startValue, value);
 71             currentValue = Interlocked.CompareExchange(ref target, desiredValue, startValue);
 72         } while (currentValue != startValue);
 73         return desiredValue;
 74     }
 75 }
 76
 77 //事件构造:自动重置事件 手动重置事件
 78 public class EventWaitHandle:WaitHandle
 79 {
 80     public Boolean Set();
 81     public Boolean Reset();
 82 }
 83 public class AutoResetEvent():EventWaitHandle
 84 {
 85     public AutoResetEvent(Boolean initialState);
 86 }
 87 public class ManualResetEvent():EventWaitHandle
 88 {
 89     public ManualResetEvent(Boolean initialState);
 90 }
 91
 92 //信号量构造
 93 public class Semaphore:WaitHandle
 94 {
 95     public Semaphore(Int32 initialCount,Int32 maxinumCount);
 96     public Int32 Release();
 97     public Int32 Release(Int32 releaseCount);
 98 }
 99
100 //互斥体构造,内部维护一个递归计数,可以实现递归锁
101 public sealed class Mutex:WaitHandle
102 {
103     public Mutex ();
104     public void ReleaseMutex();
105 }
106
107 //事件构造,信号量构造,互斥体构造均可以简单的实现自旋锁
108 public class SimpleSpinlock
109 {
110     private readonly Mutex m_lock=new Mutex();//针对互斥体构造
111     //private readonly Semaphore m_lock=new Semaphore();//针对信号量构造
112     //private readonly AutoResetEvent m_lock=new AutoResetEvent(true);//针对事件构造
113     public void Enter()
114     {
115         m_lock.WaitOne();
116     }
117     public void Leave()
118     {
119         m_lock.ReleaseMutex();//针对互斥体构造
120         //m_lock.Release(1);//针对信号量构造
121         //m_lock.Set();//针对事件构造
122     }
123 }
时间: 2024-11-03 05:25:28

[.net]基元线程同步构造的相关文章

【C#进阶系列】28 基元线程同步构造

多个线程同时访问共享数据时,线程同步能防止数据损坏.之所以要强调同时,是因为线程同步问题实际上就是计时问题. 不需要线程同步是最理想的情况,因为线程同步一般很繁琐,涉及到线程同步锁的获取和释放,容易遗漏,而且锁会损耗性能,获取和释放锁都需要时间,最后锁的玩法就在于一次只能让一个线程访问数据,那么就会阻塞线程,阻塞线程就会让额外的线程产生,阻塞越多,线程越多,线程过多的坏处就不谈了. 所以可以避免线程同步的话就应该去避免,尽量不要去使用静态字段这样的共享数据. 类库和线程安全 .net类库保证了所

Clr Via C#读书笔记----基元线程同步构造

重点在于多个线程同时访问,保持线程的同步. 线程同步的问题: 1,线程同步比较繁琐,而且容易写错. 2,线程同步会损害性能,获取和释放一个锁是需要时间. 3,线程同步一次只允许一个线程访问资源. 类库和线程安全, 一个线程安全的发那个发意味着两个线程试图同时访问数据时,数据不会被破坏. 基元用户模式和内核模式构造 基元:指代码中最简单的构造,有两种基元构造:用户模式和内核模式. 1,基元用户模式比基元内核模式速度要快,因为直接使用特殊的cpu指令来协调线程,在硬件中发生的. 2,基元用户模式构造

【C#进阶系列】29 混合线程同步构造

上一章讲了基元线程同步构造,而其它的线程同步构造都是基于这些基元线程同步构造的,并且一般都合并了用户模式和内核模式构造,我们称之为混合线程同步构造. 在没有线程竞争时,混合线程提供了基于用户模式构造所具备的性能优势,而多个线程竞争一个构造时,混合线程通过基元内核模式的构造来提供不“自旋”的优势. 那么接下来就是个简单的混合线程同步构造的例子,可与上一章最后的那些例子相比较: public class SimpleHybridLock : IDisposable { private Int32 m

第三十章 混合线程同步构造

目录: 30.1 一个简单的混合锁 30.2 自旋,线程所有权和递归 30.3 FCL中的混合构造 30.4 著名的双检锁技术 30.5 条件变量模式 30.6 并发集合类 混合线程同步构造:合并了用户模式和内核模式构造.没有线程竞争时,混合构造提供了基元用户模式构造所具有的性能优势.多个线程竞争一个构造时,混合构造通过基元内核模式的构造来提供不“自旋”的优势. 30.1 一个简单的混合锁 internal sealed class SimpleHybirdLock : IDisposable{

基元用户模式构造--互锁构造 Interlocked 实现的异步web请求实例

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net.Http; 5 using System.Text; 6 using System.Threading; 7 using System.Threading.Tasks; 8 9 namespace Test 10 { 11 enum CoordinationStatus 12 { 13 AllDone, 14 Ca

【C#】C#线程_混合线程的同步构造

目录结构: contents structure [+] 一个简单的混合锁 FCL中的混合锁 ManualResetEventSlim类和SemaphoreSlim类 Monitor类和同步块 ReaderWriterLockSlim类 CountdownEvent类 Barrier类 双检锁技术 异步线程的同步构造 并发集合类 在之前的文章中,我们分析过C#线程的基元线程同步构造,在这篇文章中继续分析C#线程的混合线程的同步构造. 在之前的分析中,谈到了基元用户模式的线程构造与内核模式的线程构

.NET面试题解析(07)-多线程编程与线程同步

系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等,本文只是从常见面试题的角度(也是开发过程中常用)去深入浅出线程相关的知识.如果想要系统的学习多线程,没有捷径的,也不要偷懒,还是去看专业书籍的比较好. 常见面试题目: 1. 描述线程与进程的区别? 2. 为什么GUI不支持跨线程访问控件?一般如何解决这个问题? 3. 简述后台线程和前台线程的区别? 4. 说说常

异步编程(二)用户模式线程同步

基元线程同步构造 多个线程同时访问共享数据时,线程同步能防止数据损坏.不需要线程同步是最理想的情况,因为线程同步存在许多问题. 第一个问题就是它比较繁琐,而且很容易写错. 第二个问题是,他们会损害性能.获取和释放锁是需要时间的. 第三个问题是,他们一次只允许一个线程访问资源,就可能导致其他线程被阻塞,使用多线程是为了提高效率,而阻塞无疑降低了你的效率. 综上所述,线程同步是一件不好的事情,所以在设计自己的应用程序时,应尽可能避免进行线程同步.具体就是避免使用像静态字段这样的共享数据.线程用new

CLR 线程同步

CLR 基元线程同步构造 <CLR via C#>到了最后一部分,这一章重点在于线程同步,多个线程同时访问共享数据时,线程同步能防止数据虽坏.之所以要强调同时,是因为线程同步问题其实就是计时问题.为构建可伸缩的.响应灵敏的应用程序,关键在于不要阻塞你拥有的线程,使它们能用于(和重用于)执行其他任务. 不需要线程同步是最理想的情况,因为线程同步存在许多问题: 1 第一个问题是,它比较繁琐,很容易出错. 2 第二个问题是,它们会损坏性能.获取和释放锁是需要时间的,因为要调用一些额外的方法,而且不同