一:线程同步
由于现代计算机CPU的多线程技术普及,所有的资源访问都要面临一个问题:在多线程情况下,如何有序访问资源?为此,线程同步技术应运而生。
线程同步的技术分三类:
1.排它锁:
排它锁,顾名思义,独占(资源)、排他(其他线程或者进程)。排它锁每一次只允许一个线程执行特定的活动或者代码。其目的是让所有线程共享写的状态,但相互之间不受影响。排它锁有以下几种:
①Moniter(lock)
②Mutex
③SpinkLock
以下详细解释每一种锁:
Lock锁:
这种锁最常见最常用的一种结构,其他两种锁多样于处理特定的场景。这种锁保证每一次只有一个线程锁定同步对象,其他线程则被阻塞,直到锁的释放。如果参与竞争的锁有多个,则它们需要在准备队列中排队等待,并以先到先得的方式获得资源的访问权(个别平台版本或者运行环境有细微差异,无法保证完全如此)。排它锁强制以顺序方式访问被锁访问的资源,从而实现了被访问资源的有序访问。另外,Lock锁其实是Moniter锁的语法糖,其实现底层是运用Moniter实现的。
Mutex锁:
这种锁的威力巨大,应用广泛,既可以实现线程访问资源的限制,又可以实现进程之间的访问限制。这是一种经典且应用广泛的技术,在windows及unix系统中均可以使用。其典型的使用语句:mutex.WaitOne()和mutex.ReleaseMutex().
SpinkLock:
可用于实现微优化,可以在高并发的场景下减少上下文切换,提高允许效率。但如果使用不当,则会造成CPU使用率升高,为了改进其缺点,在此基础上出现了混合锁,其原理大致为:在规定的时间限制内其首先为自旋锁,如果超时后还未完成,则转为排他锁。
说明:
同步对象一般选择在各个参与的线程中都是可见的对象,但该对象必须是引用类型的对象,而且通常是私有的(因为通常用于封装逻辑)。另外锁之间可以嵌套,在嵌套时,线程会只阻塞在最外层的锁上。
2.非排它锁
①semaphore
②ReaderWriterLock
首先说semaphore,这种结构会定义一个线程容量及同时访问资源的线程容量。通过调整线程总容量及访问容量来限制资源访问的并发性。这种结构也可以用于跨进程对资源的访问限制,但仅限于windows平台,而Mutex也可以在unix平台下工作。这种结构较复杂切耗时较多,目前其轻量级的实现semaphoreslim已经大行其道,因为其已经进行了一系列优化以减少了并发延迟。
再说ReaderWriterLock.这种锁如同其名称一样,主要用来对读多写少的业务场景设计的,这种结构有两种锁:读锁和写锁。两种锁的排斥关系为:读读不限制,读写限制,写读限制。或者说读锁兼容其他的读锁,而写锁是全局性的排他锁。这种锁使用的时候有一个很细微且非常关键的场景:假如先读后写,那么在锁转换的时候(因为开始是先读,读锁之间没有限制,当一个线程开始转换为写锁时,不幸被别的线程捷足先登,抢先获得了写锁并完成了写锁),当线程获取写锁后发现资源与当初读的时候不一致怎么办?换句话说,读锁与写锁之间是独立的且不是原子的,在两种锁转换之间,对象资源发生了变化,如果再进一步对资源进行写入,岂不是驴唇不对马嘴了?别说,还真有聪明人,早就想到了这个问题并且解决了这个问题,解决的关键在于,设计者将读锁转换写锁的这个环节设计成了原子级别,这样就不会存在读写割裂问题了,也就避免了写入脏数据问题,而这种方案称之为:可升级锁。
3.信号发送机构
最简单的信号发送记过是事件等待句柄,其有三种实现方式,分别为:AutoResetEvent,ManualresetEvent,CountdownEvent。
详情(待补充)
标签:同步,限制,c#,访问,读锁,线程,排它,资源 From: https://www.cnblogs.com/jizhong/p/18462205