使用信号量时,为什么这4个线程会锁定?

时间:2018-04-27 13:05:32

标签: c# multithreading locking semaphore race-condition

在可能有许多线程的系统中,我试图确保一次只实例化一个类的四个实例,并且可能在5-60秒后释放。实例在每个线程的开头创建,并在线程中的进程结束时销毁。

我还想防止一次只构建一个实例。所以我的逻辑是在Object实例化期间使用锁,但也用信号量包装整个线程逻辑。

private static readonly object padlock = new object();
private static readonly Semaphore mutablelock = new Semaphore(0, 4);

// called at the start of a long running thread
public static Object GetNewInstance()
{
    // semaphore used to prevent more than 4 objects from existing at any time
    mutablelock.WaitOne();

    // lock used to prevent more than one object being instantiated at a time
    lock (padlock)
    {
        var instance = new Object();
        return instance;
    }
}

// called at the end of a long running thread
public static void ReleaseInstance()
{
    mutablelock.Release();
}

该程序有四个线程(当使用调试停止点查看时),每个线程都停在mutablelock.WaitOne();行,并且不会再继续前进。

1 个答案:

答案 0 :(得分:0)

您正在构建Semaphore,以便保留所有条目。 Semaphore constructor taking two arguments可以这样说:

  

如果 initialCount 小于 maximumCount ,则效果与当前线程调用WaitOne maximumCount )的效果相同减去 initialCount )次。如果您不想为创建信号量的线程保留任何条目,请对 maximumCount initialCount 使用相同的编号。

所以做出这样的改变:

private static readonly Semaphore mutablelock = new Semaphore(4, 4);