我有一个多线程应用程序,其中一个类使用信号量来控制读取和读取。写作。这似乎在大多数情况下工作得很好,但是我得到一些莫名其妙的semaphorefull异常抛出,表明我试图释放我不应该。问题是我已经完成了我的代码和工作。似乎无法找到导致这种情况发生的逻辑缺陷。
如果有人可以查看下面的示例代码,我将非常感激。让我知道我在哪里出错了,因为在这个阶段我觉得我开始发疯了。
请注意,“真正的”代码不只是有一个线程循环,而是非常接近
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
Thread t = new Thread(() => ThreadA());
t.Start();
}
}
/// <summary>
/// Run the methods in the worker class
/// </summary>
private static void ThreadA()
{
Token token = null;
WorkClass workClass = new WorkClass();
try
{
workClass.BeginRead(out token, "A");
}
finally
{
workClass.EndRead(token);
}
}
}
/// <summary>
/// this class does the actual work
/// </summary>
public class WorkClass
{
private Semaphore _pool = new Semaphore(2, 2);
public void BeginRead(out Token token, string s)
{
Semaphore sem = null;
try
{
// wait for the main semaphore to signal
_pool.WaitOne();
// set local semaphore equal to main
sem = _pool;
//simulate work
Thread.Sleep(100);
}
finally
{
//return the token with the semaphore
token = new Token(sem, s);
}
}
public void EndRead(Token token)
{
try
{
// do some more work
}
finally
{
// release the semaphore if not null
if (null != token.signal)
{
token.signal.Release();
}
}
}
}
public class Token
{
internal readonly Semaphore signal;
internal readonly string s;
internal Token(Semaphore _signal, string _s)
{
this.s = _s;
this.signal = _signal;
}
}
答案 0 :(得分:3)
您将遇到的一个问题是,您正在为WorkClass
的每个实例创建一个新的信号量。因此,如果您有三个WorkClass
个实例,则会有三个单独的信号量。我认为您希望您的信号量为static
,以便所有实例共享一个信号量。您将其称为_pool
,因此我假设您希望所有实例都访问的共享资源数量有限。
我看不出您在问题中提供的代码如何抛出SemaphoreFullException
。您确定您发布的代码在功能上等同于您遇到问题的代码吗?如果你编译并运行你发布的代码,你会得到那个例外吗?
答案 1 :(得分:2)
Semaphore
IDisposable
到WaitHandle - 你需要WorkerClass
Dispose
当它Dispose
- d。
public class WorkClass : IDisposable
using (WorkClass workClass = new WorkClass())
由于unDisposed Semaphore实例,您可能在加载时遇到了一些系统限制?这可能不是 问题,但它是 A 问题,无论您进行任何重新设计以使pool
静态或其他单例机制。
答案 2 :(得分:0)
您在工作类之外传递信号量(包含在Token
实例中)的事实可能表明您正在其他地方使用它,BeginRead
和EndRead
如果仅在WorkClass
内使用信号量,我强烈建议您将其从Token
中完全删除 - 将其设为私有静态字段(如Jim pointed out)并将其隐藏世界其他地方。