我试图了解我的应用程序是否因为缓慢的I/O (计算开销很大的算法)或对资源的互斥访问而挂起。在这种情况下,使用接口并在可能导致锁定的类中实现它们,可能会避免锁定或不锁定。
我知道Interface是一种编程结构,在这种结构中,我们定义了我们希望公开给公共或其他模块的函数/服务,并避免循环依赖。
发布于 2014-01-08 09:36:53
不,接口与死锁完全无关。如果您有一个死锁,那么根据定义,这是因为对共享资源的同步访问不会减慢I/O):
死锁是这样一种情况,即两个或多个相互竞争的动作都在等待对方完成,因此两者都没有。
如何调试?
死锁可能有很多原因(当然,某些条件--慢I/O、CPU密集型算法--可能会导致死锁出现得更频繁,但它们并不是造成死锁的原因)。
大多数情况下,如果可以将调试器附加到应用程序,则很容易检测到它们。挂起时暂停执行,查看线程列表和它们的堆栈,您可以看到它们是否在等待共享资源。
一个非常常见的死锁场景是:
另一种非常常见的情况是:
lock语句,而是直接使用Monitor.Enter()或其他同步原语(如ReadWriterLockSlim) )。这是一个代码示例(我知道非常天真的锁机制):
object _syncRoot = new object();
void ThreadWorker(object state ) {
Monitor.Enter(_syncRoot);
try {
// Do some operation that may fail
// Release lock
Monitor.Exit(_syncRoot);
}
catch (Exception e) {
// Log error
}
}幸运的是,这是非常容易避免的(检查这个答案以查看锁如何实现监视器)。
try {
lock (_syncRoot) {
// Do your job here
}
}在以前的场景中,如果重新访问此锁(但其他线程将挂起)相同的线程不会挂起,但是如果您使用的是读/写锁,那么它就会挂起(或者如果它不支持重入,请参阅这个问题了解其他细节)。如果您对锁使用超时(当然,这并不总是可能的),则可能会检测到这种故障。当锁尝试超时时,应用程序将检测到它并采取适当的操作(如果有的话,它甚至可以优雅地中止)。
发布于 2014-01-08 09:32:58
不是的。相反,由于接口隐藏了实现,所以很难看到导致问题的锁。
使用调试器的Debug + Windows + Threads查看哪些线程正在运行,哪些线程正在执行获取锁的代码。您还可以看到拥有锁的线程的线程ID,请检查这个答案。
发布于 2014-01-08 09:44:28
接口不会改变代码在运行时执行的内容。锁定纯粹是运行时的事情。对于死锁,只有实际执行的代码才重要。如何调用方法并不重要。
https://stackoverflow.com/questions/20991257
复制相似问题