在一个服务器应用程序中,我们有以下内容:
一个名为JobManager的单例类。
另一个类Scheduler,它不断检查是否到了将任何类型的作业添加到JobManager的时间。
当该执行时,Scheduler会执行以下操作:
在NewJobItem方法中,我有类似以下的代码:
这里发生了一个死锁,发生在系统到达这个点(CS.Acquire)时。客户端和服务器应用程序之间的通信是通过Indy 10进行的。我认为,触发服务器应用程序方法并向JobManager发送消息的RPC调用正在Indy线程的上下文中运行。
调度程序有自己的线程运行,并且直接调用JobManager方法。这种情况容易导致死锁吗?有人能帮我理解为什么会出现死锁吗?
我们知道,有时候当客户端执行特定操作时,会导致系统锁定,然后我最终找到了这个关键点,在同一类的关键部分被从不同的点(调度程序和JobManager的消息处理方法)访问两次。
还有一些额外的信息需要补充,我想说的是(这可能很愚蠢,但无妨),DoSomething中还有另一个 。
当该执行时,Scheduler会执行以下操作:
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线程的上下文中运行。
调度程序有自己的线程运行,并且直接调用JobManager方法。这种情况容易导致死锁吗?有人能帮我理解为什么会出现死锁吗?
我们知道,有时候当客户端执行特定操作时,会导致系统锁定,然后我最终找到了这个关键点,在同一类的关键部分被从不同的点(调度程序和JobManager的消息处理方法)访问两次。
还有一些额外的信息需要补充,我想说的是(这可能很愚蠢,但无妨),DoSomething中还有另一个 。
CS.Acquire;
try
Do other stuff...
finally
CS.Release;
end;
这个内部的CS.Release会对外部的CS.Acquire造成影响吗?如果是的话,这就可能是调度器进入临界区的时候,所有的锁定和解锁都变得混乱的地方。