详解详解C#多线程之线程同步多线程之线程同步
本文主要介绍了C#线程同步的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
多线程内容大致分两部分,其一是异步操作,可通过专用,线程池,Task,Parallel,PLINQ等,而这里又涉及工作线程与IO
线程;其二是线程同步问题,鄙人现在学习与探究的是线程同步问题。
通过学习《CLR via C#》里面的内容,对线程同步形成了脉络较清晰的体系结构,在多线程中实现线程同步的是线程同步构
造,这个构造分两大类,一个是基元构造,一个是混合构造。所谓基元则是在代码中使用最简单的构造。基原构造又分成两
类,一个是用户模式,另一个是内核模式。而混合构造则是在内部会使用基元构造的用户模式和内核模式,使用它的模式会有
一定的策略,因为用户模式和内核模式各有利弊,混合构造则是为了平衡两者的利与弊而设计出来。下面则列举整个线程同步
体系结构
基元基元
1.1 用户模式
1.1.1 volatile
1.1.2 Interlock
1.2 内核模式
1.2.1 WaitHandle
1.2.2 ManualResetEvent与AutoResetEvent
1.2.3 Semaphore
1.2.4 Mutex
混合混合
2.1 各种Slim
2.2 Monitor
2.3 MethodImplAttribute与SynchronizationAttribute
2.4 ReaderWriterLock
2.5 Barier(少用)
2.6 CoutdownEvent(少用)
先从线程同步问题的原因说起,当内存中有一个整形的变量A,里面存放的值是2,当线程1执行的时候它会把A的值从内存中取
出存放到CPU的寄存器中,并把A赋值为3,此时刚好线程1的时间片结束;接着CPU把时间片分给线程2,线程2同样把A从内
存中的值取出来放到内存中,但是由于线程1并没有把变量A的新值3放回内存,故线程2读到的仍然是旧的值(也就是脏数
据)2,然后线程2要是需要对A值进行一些判断之类的就会出现一些非预期的结果了。
而针对上面这种对资源的共享问题处理,往往会使用各种各样办法。下面则逐一介绍
先说说基元构造中的用户模式,凡是用户模式的优点是它的执行相对较快,因为它是通过一系列CPU指令来协调,它造成的
阻塞只是极短时间的阻塞,对操作系统而言这个线程是一直在运行,从未被阻塞。缺点就是唯有系统内核才能停止这样的一个
线程运行。另一方面就是由于线程在自旋而非阻塞,那么它还会占用这CPU的时间,造成对CPU时间的浪费。
首先是基元用户模式构造中的volatile构造,这个构造网上很多说法是让CPU对指定字段(Field,也就是变量)的读都是从内
存读,每次写都是往内存写。然而它和编译器的代码优化有关系。先看看如下代码
public class StrageClass
{
vo int mFlag = 0;
int mValue = 0;
public void Thread1()
{
mValue = 5;
mFlag = 1;
}
public void Thread2()
{
if (mFlag == 1)
Console.WriteLine(mValue);
}