AutoResetEvent和信号量与maximumCount = 1之间有什么区别吗?

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.

所以这里是差异的总结:

  • A Semaphore的状态是手动控制的.
  • AutoResetEvent的状态被手动设置,但自动复位.
  • 随着Semaphore线程通常平衡ReleaseWaitOne电话.
  • 随着AutoResetEvent一个线程通常被指定为信号装置,另一个是服务员.
  • Semaphore节流访问资源或代码块.
  • A 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方法将工作方式相同,但ReleaseSet方法不会.正是由于这个原因,二进制信号量不能与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)

  • 他询问了信号量最大为1的信号量。 (2认同)

Ric*_*key 5

An AutoResetEvent, 使用Joe Albahari 的比喻

就像一个票闸:插入一张票只让一个人通过

所以它就像一扇单向门。

相比之下,Semaphore计数为 1 的 a 就像一个只能容纳一个人的房间,并且有一个“Occupied”标志。信号量用于控制对资源(房间)的访问,计数指定有多少资源(房间里可以容纳多少人)。