如何用显示器替换此信号量?

Kur*_*rru 4 c# multithreading semaphore monitor race-condition

在我之前的一个问题中,有人曾暗示使用信号量与使用显示器相比在C#中使用信号量昂贵.所以我问这个问题,如何用监视器替换此代码中的信号量?

我需要function1在function2(在一个单独的线程中)完成后返回它的值.我已经替换了Semaphore.WaitOnea Monitor.WaitSemaphore.Releasea,Monitor.PulseAll但是PulseAllWait导致程序挂起之前被触发了.知道如何避免这种竞争条件吗?

Semaphore semaphore = new Semaphore(0,1);
byte b;
public byte Function1()
{
    // new thread starting in Function2;

    semaphore.WaitOne();
    return b;
}

public void Function2()
{
    // do some thing
    b = 0;
    semaphore.Release();
}
Run Code Online (Sandbox Code Playgroud)

Ree*_*sey 9

您可以使用WaitHandle而不是Semaphore来完成此操作.这将是最简单的替代方案,并且比信号量表现更好:

ManualResetEvent manualResetEvent = new ManualResetEvent(false);
byte b;
public byte Function1()
{
    // new thread starting in Function2;

    manualResetEvent.WaitOne();
    return b;
}

public void Function2()
{
    // do some thing
    b = 0;
    manualResetEvent.Set();
}
Run Code Online (Sandbox Code Playgroud)

  • 为了向其他读者进一步解释这个答案 - 只有当你需要允许一些固定数量的线程> 1来获取共享资源时,才需要"信号量".它类似于`Monitor`,但它们都不是原始问题的正确语义,它试图解决"等到这个操作完成后"的问题.对于那些语义,等待句柄(`ManualResetEvent/AutoResetEvent`通常比临界区(`lock` /`Monitor`)更合适. (3认同)