在服务器应用程序上,我们有以下内容:
一个称为 JobManager 的单例类。
另一个类是 Scheduler,它不断检查是否需要向 JobManager 添加任何类型的作业。
当需要这样做时,调度程序会执行以下操作:
TJobManager.Singleton.NewJobItem(parameterlist goes here...);
同时,在客户端应用程序上,用户执行一些操作来生成对服务器的调用。在内部,服务器向自身发送一条消息,监听该消息的类之一是 JobManager。
JobManager 处理该消息,并知道是时候将新作业添加到列表中,调用它自己的方法:
NewJobItem(parameter list...);
在 NewJobItem 方法中,我有这样的内容:
CS.Acquire;
try
DoSomething;
CallAMethodWithAnotherCriticalSessionInternally;
finally
CS.Release;
end;
恰好系统此时陷入死锁(CS.Acquire)。
客户端和服务器应用程序之间的通信是通过 Indy 10 进行的。
我认为,触发向 JobManager 发送消息的服务器应用程序方法的 RPC 调用正在 Indy 线程的上下文中运行。
Scheduler有自己的线程在运行,它直接调用JobManager方法。这种情况容易陷入僵局吗?
有人可以帮助我理解为什么这里会发生僵局吗?
我们知道,有时,当客户端执行特定操作时,导致系统锁定,那么我最终可以找到这一点,即从不同的点(调度程序和JobManager 的消息处理程序方法)。
更多信息
我想补充一点(这可能很愚蠢,但无论如何......)在 DoSomething 中还有另一个
CS.Acquire;
try
Do other stuff...
finally
CS.Release;
end;
这个内部 CS.Release 对外部 CS.Acquire 做了什么?如果是这样,这可能是调度程序进入关键部分的点,并且所有锁定和解锁都会变得一团糟。