在一次采访中,被要求识别以下代码中的bug(如果有)。
下面的类实现了具有一定容量的信号量。
public class MySemaphore
{
private object _mutex = new object();
private int _currAvail;
public MySemaphore(int capacity)
{
_currAvail = capacity;
}
public void Wait()
{
lock (_mutex)
{
if (_currAvail == 0) Monitor.Wait(_mutex);
_currAvail--;
}
}
public void Signal()
{
lock (_mutex) {
_currAvail++;
Monitor.Pulse(_mutex);
}
}
}
2条答案
按热度按时间euoag5mw1#
充分披露:我不使用C#。我不熟悉
Monitor.Wait(o)
和Monitor.Pulse(o)
,但我相信,如果允许两个或更多线程同时调用sema.Wait()
,_currAvail
可能会变为负值。假设线程A和线程C同时调用
sema.Wait()
,而线程B调用sema.Signal()
。修复方法是在
Monitor.Wait(_mutex)
返回后重新检查_currAvail
。即,在循环中调用Monitor.Wait(_mutex)
:lmyy7pcs2#
我发现此信号量存在以下问题:
capacity
实际上只是初始容量,而不是总容量。因此,只需调用Signal
1000次,就可以获得1000个额外容量。int.MaxValue
作为初始容量,然后将Signal
作为初始容量,则当前容量将为int.MinValue
。