同步基元概述

原创 2007年09月22日 14:18:00
&nbs

HTML Tags and JavaScript tutorial



同步基元概述





.NET Framework 提供了一系列同步基元来控制线程交互并避免争用条件。这可大致分为三个类别:锁定、通知和联锁操作。
上述类别的定义并非是绝对的:有些同步机制具有多个类别的特征;一次释放一个线程的事件的功能类似于锁定;任何锁定的释放都可看作一个信号;而联锁操作可用于构造锁定。但是,这些类别仍然是有用的。
记住线程同步是协作这一点非常重要。只要有一个线程避开同步机制直接访问受保护的资源,该同步机制就不是有效的。
锁定
锁向一个线程一次提供一个资源的控制功能,或者向指定数目的线程提供此功能。请求正在使用中的独占锁的线程会被阻止,直到该锁变为可用为止。
独占锁
锁定的最简单的形式是 C# 的
lock
语句(在 Visual Basic 中为
SyncLock
),该语句可控制对代码块的访问。这种块通常称为临界区。
lock
语句使通过使用
Monitor
类的
Enter

Exit
方法实现的,它使用
try…catch…finally
确保该锁被释放。
通常情况下,使用
lock
语句保护小代码块并且不跨越多个方法是使用
Monitor
类的最佳方法。
Monitor
类功能强大,但是容易形成孤立锁和死锁。
Monitor 类
Monitor
类提供了附加功能,可结合
lock
语句使用:


TryEnter
方法允许当前被阻止,正在等待资源的线程在指定时间间隔之后放弃。它返回一个指示成功或失败的布尔值,可用于检测和避免潜在的死锁。



Wait
方法由临界区中的线程调用。它放弃对资源的控制并阻止,直到该资源重新可用为止。



Pulse

PulseAll
方法允许要释放锁或调用
Wait
的线程将一个或多个线程放入就绪队列,以使它们能够获取锁。

Wait
方法重载的超时允许等待线程进入就绪队列。
如果用于锁的对象派生自
MarshalByRefObject
,则
Monitor
类可在多个应用程序域中提供锁定。
Monitor
具有线程关联。也就是说,进入监视器的线程必须通过调用
Exit

Wait
才能退出。
Monitor
类不可实例化。其方法是静态(在 Visual Basic 中为
Shared
)方法,用于可实例化的锁对象。
有关概念性概述,请参见
监视器

Mutex 类
线程通过调用其
WaitOne
方法的重载请求
Mutex
。提供了具有超时的重载,以便允许线程放弃等待。与
Monitor
类不同,mutex 可以是局部的,也可以是全局的。全局 mutex(也称为命名的 mutex)在整个操作系统中可见,可用于在多个应用程序域或进程中同步线程。局部 mutex 派生自
MarshalByRefObject
,可以跨应用程序域边界使用。
此外,
Mutex
派生自
WaitHandle
,这意味着它可用于
WaitHandle
提供的通知机制,如
WaitAll

WaitAny

SignalAndWait
方法。

Monitor
一样,
Mutex
具有线程关联。与
Monitor
不同,
Mutex
是可实例化的对象。
有关概念性概述,请参见
Mutex

其他锁
锁定不必是独占的。允许有限数目的线程并发访问某个资源通常十分有用。信号量和读写器锁旨在控制此类池资源访问。
ReaderWriterLock 类
ReaderWriterLock
类用于更改数据的线程(编写器)必须独占访问某个资源的情形。如果编写器不是活动的,则任何数量的读取器均可通过调用
AcquireReaderLock
方法访问该资源。一旦有线程调用
AcquireWriterLock
方法,后续读取器请求则会阻止,直到所有现有读取器均释放了该锁,并且有一个编写器获取并释放了该锁为止。
ReaderWriterLock
具有线程关联。
有关概念性概述,请参见
读取器/编写器锁

Semaphore 类
Semaphore
类允许指定数目的线程访问某个资源。请求该资源的其他线程会一直阻止,直到某个线程释放信号量为止。

Mutex
类一样,
Semaphore
派生自
WaitHandle

Semaphore
也与
Mutex
一样,可以是局部的,也可以是全局的。它可以跨应用程序域边界使用。

Monitor

Mutex

ReaderWriterLock
不一样,
Semaphore
不具有线程关联。这意味着它可以用于一个线程获取信号量而另一个线程释放该信号量的情形。
有关概念性概述,请参见
信号量

通知
等待另一个线程的信号的最简单方法是调用
Join
方法,该方法会一直阻止,直到另一个线程完成为止。
Join
有两个重载方法,这两个方法允许阻止的线程在等待指定时间间隔之后跳出等待。
等待句柄提供了更为丰富的等待和通知功能。
等待句柄
等待句柄派生自
WaitHandle
类,后者又派生自
MarshalByRefObject
。因此,等待句柄可用于跨应用程序域边界同步线程的活动。
通过调用实例方法
WaitOne
或者静态方法
WaitAll

WaitAny

SignalAndWait
中的一个方法,线程可由等待句柄阻止。它们的释放方式取决于调用的方法以及等待句柄的种类。
有关概念性概述,请参见
等待句柄

事件等待句柄
事件等待句柄包括
EventWaitHandle
类及其派生类
AutoResetEvent

ManualResetEvent
。当通过调用
Set
方法或使用
SignalAndWait
方法通知事件等待句柄时,线程会从事件等待句柄释放。
事件等待句柄要么自动重置自身(类似于每次得到通知时只允许一个线程通过的旋转门),要么必须手动重置(类似于在通知前一直关闭,有人将其关闭前则一直打开的大门)。顾名思义,
AutoResetEvent

ManualResetEvent
分别表示前者和后者。
EventWaitHandle
可表示这两种类型的事件,并且既可以是局部的也可以是全局的。派生类
AutoResetEvent

ManualResetEvent
始终是局部的。
事件等待句柄不具有线程关联。任何线程都可以通知事件等待句柄。
有关概念性概述,请参见
EventWaitHandle、AutoResetEvent 和 ManualResetEvent

Mutex 和 Semaphore 类
因为
Mutex

Semaphore
类派生自
WaitHandle
,所以它们可用于
WaitHandle
的静态方法。例如,线程可以使用
WaitAll
方法等待,直到满足以下三个条件为止:
EventWaitHandle
接收到通知,
Mutex
已释放,
Semaphore
已释放。类似地,线程可以使用
WaitAny
方法等待,直到满足上述所有条件为止。
对于
Mutex

Semaphore
,接收到通知即意味着被释放。如果上述两个类型之一用作
SignalAndWait
方法的第一个参数,该类型即被释放。对于具有线程关联的
Mutex
,如果进行调用的线程不具有该 mutex,则会引发异常。如前所述,信号量不具有线程关联。
联锁操作
联锁操作是由
Interlocked
类的静态方法对某个内存位置执行的简单原子操作。这些原子操作包括添加、递增和递减、交换、依赖于比较的条件交换,以及 32 位平台上的 64 位值的读取操作。



注意




原子性的保证仅限于单个操作;如果必须将多个操作作为一个单元执行,则必须使用更粗粒度的同步机制。



尽管这些操作中没有一个是锁或信号,但它们可用于构造锁和信号。因为它们是 Windows 操作系统固有的,因此联锁操作的执行速度非常快。
联锁操作可用于可变内存保证,以编写展示功能强大的非阻止并发的应用程序,但是,它们需要复杂的低级别编程,因此大多数情况下简单锁是更好的选择。
有关概念性概述,请参见
互锁操作

请参见
概念
为多线程处理同步数据
监视器
Mutex
信号量
等待句柄
互锁操作
读取器/编写器锁
其他资源
EventWaitHandle、AutoResetEvent 和 ManualResetEvent
 


p;
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

同步基元-监视器Monitor的TryEnter方法应用

Monitor的TryEnter方法,不管获得或没获得锁都会立既返回False,如果得到锁就返回True,它不必像Enter方法那样没有得到锁就等待。 所以通过这个特征我们可以指示线程在获得锁的情况...

软件人员需把握物质能量信息三基元

人们常把物质、能量和信息相提并论,如称它们为人类社会发展可利用的三种基本资源,也有人称它们为组成世界的三基元。前者从人类社会可利用资源的角度把它们并列为三种基本资源,似有一定道理;但后者把它们并列为组...

自然场景下植物图像的基元检测

一.图像的Canny算计运用与角点检测1.1代码详解# 角点检测 def work01(): img = ndimage.imread('flower.jpg', 'L')#这里是你图片的路径...

亚像素边缘的直线及圆弧的基元分割

从20世纪70年代起就有不少专家提出了一些有效的亚像素边缘定位的方法,如插值法、灰度矩法和一些组合的算法等。本文在前辈的基础上描述一种图像亚像素边缘检测方法,用Sobel算子和多边形逼近的方法实现亚像...

15.6.2 定义基元

15.6.2 定义基元       首先要定义将要处理的值类型,然后,实现几个可以在以后组合的基元。基元数据类型叫 Contract,表示可能出现在特定日期和时间的交易。   ...

集成性能基元(ipp)

Intel公司有一个产品叫集成性能基元(Integrated Performance Primitives,IPP)库。这个库实际上是一个有着高性能内核的工具箱,它主要用于多媒体处理以及其他计算密集型...

AS3中的八种基元类型

变量的实际类型并不取决于它的变量类型注释,在AS3中,变量类型注释仅是比编译器用的。   一,八种基元类型 何谓基元类型?即是一门语言中最基本基本的数据类型,其它数据类型均是以此为基础定...

13.1.4 创建基元工作流

13.1.4 创建基元工作流     F# PowerPack 库包含许多重要的 I/O 操作异步版本,但是,它可不能包括所有。为此,F# 库还提供了构建自己的基元工作流的方法。如果要运...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)