brA*_*i64 17 c# multithreading
我正在阅读以下文章:
http://www.albahari.com/threading
我无法理解AutoResetEvent和用maximumCount = 1初始化的信号量之间的区别.只是为了看看我是否正确...这两种结构有什么不同,给定使用?
谢谢!
Bri*_*eon 19
是的,确实存在差异.A Semaphore用于限制对资源或代码块的访问.当WaitOne被称为线程将阻塞,直到从信号计数变为可用.为了使计数可用,你会打电话Release.最大计数为1的信号量通常称为二进制信号量.这种性质的信号量只允许从单个线程访问资源或块代码.您可以使用二进制信号量代替互斥锁或监视器.要记住的重要一点Semaphore是它的状态是通过调用和手动控制的.WaitOneRelease
一个AutoResetEvent在另一方面,主要是用来作为信令机制.一个线程将通过调用来阻止WaitOne等待信号.另一个线程将调用Set以启动该信号.ARE将此信号发布到一个且仅一个线程,然后立即将ARE重置为未信号状态.需要记住的重要一点AutoResetEvent是,它通过调用手动发出信号,Set并在单次调用返回后自动重置WaitOne.
所以这里是差异的总结:
Semaphore的状态是手动控制的.AutoResetEvent的状态被手动设置,但自动复位.Semaphore线程通常平衡Release和WaitOne电话.AutoResetEvent一个线程通常被指定为信号装置,另一个是服务员.Semaphore节流访问资源或代码块.AutoResetEvent表示线程采取某些行动.把它想象AutoResetEvent成走廊的大门.在收到命令后,门将允许一个人和一个人通过门.一旦一个人进门,它立即关闭并等待另一个命令.只要门继续接收新命令,走廊就可以自由地填充与给定命令数量一样多的人.
把它想象Semaphore成同一个走廊的门.门将允许走廊里的一定数量的人.门保持打开,直到走廊达到占用限制,此时门关闭.当有人离开走廊通过另一侧后,这扇门再次打开.
更新:
这是最简单的可能示例,表明某些事情明显不同.
static void Main()
{
var are = new AutoResetEvent(false);
are.Set();
are.Set();
var semaphore = new Semaphore(0, 1);
semaphore.Release();
semaphore.Release();
}
Run Code Online (Sandbox Code Playgroud)
毫无疑问,你会在第二次semaphore.Release通话时得到一个例外,而第二次通话则Set通过就好了.原因是因为ARE正在设置布尔标志,而信号量正在尝试增加计数.
该WaitOne方法将工作方式相同,但Release和Set方法不会.正是由于这个原因,二进制信号量不能与ARE互换.但是,在某些情况下,ARE可以与二进制信号量互换.
存在重叠的一种情况是针对单个线程的锁存器的情况.
public static void Main()
{
var latch = new AutoResetEvent(false);
new Thread(
() =>
{
latch.WaitOne(); // Wait for the latch.
}).Start();
latch.Set(); // Release the latch.
}
Run Code Online (Sandbox Code Playgroud)
这是一个只能通过a来满足的场景AutoResetEvent.
static void Main()
{
var are = new AutoResetEvent(false);
new Thread(
() =>
{
while (true)
{
are.WaitOne();
Console.WriteLine("go");
Thread.Sleep(2000);
}
}).Start();
while (true)
{
are.Set();
Console.WriteLine("pulse");
Thread.Sleep(1000);
}
}
Run Code Online (Sandbox Code Playgroud)
An AutoResetEvent, 使用Joe Albahari 的比喻:
就像一个票闸:插入一张票只让一个人通过
所以它就像一扇单向门。
相比之下,Semaphore计数为 1 的 a 就像一个只能容纳一个人的房间,并且有一个“Occupied”标志。信号量用于控制对资源(房间)的访问,计数指定有多少资源(房间里可以容纳多少人)。