.net 多线程调试技术
我想知道是否有人知道一份关于多线程应用程序调试技术的调查报告。理想情况下,我正在寻找基于案例的分析:死锁、饥饿、损坏的共享状态.net 多线程调试技术,.net,multithreading,debugging,.net,Multithreading,Debugging,我想知道是否有人知道一份关于多线程应用程序调试技术的调查报告。理想情况下,我正在寻找基于案例的分析:死锁、饥饿、损坏的共享状态 .Net专用或通用。不是您想要的,但您可能会觉得有趣。您也可以看看Intel的或和,尽管它们不是免费的。还可以查看Intel的文章。我使用了Helgrind作为Valgrind的一个子目录。Helgrind是一个线程错误检测器,我在一些代码中使用过一两次它来检测竞争条件。它可以检测到以下情况 POSIX pthreads API的滥用 锁排序问题引起的潜在死锁 数据竞争
.Net专用或通用。不是您想要的,但您可能会觉得有趣。您也可以看看Intel的或和,尽管它们不是免费的。还可以查看Intel的文章。我使用了Helgrind作为Valgrind的一个子目录。Helgrind是一个线程错误检测器,我在一些代码中使用过一两次它来检测竞争条件。它可以检测到以下情况
显然是Linux工具,用于系统程序,C/C++。没有Java或.NET。
我还不知道有哪篇文章或书能说明你在寻找什么,所以这里是我在Windows(非托管和托管)上12年多线程调试的“经验教训” 正如我在评论中所说,我的大多数“多线程调试”实际上是通过手动代码检查来完成的,以查找这些问题 死锁和损坏的共享状态 记录(订单和它们保护的共享状态),并确保它们的一致性。这解决了大多数死锁问题和损坏的共享状态问题 (注意:上面的“锁层次结构”链接指的是Herb Sutter的Dobbs博士的一篇文章;他写了一系列我极力推荐的文章) 更多关于死锁的信息 使用。这样可以确保在遇到异常时释放锁。宁愿使用“lock”语句,也不要使用try/finally (请注意,.NET中的RAII依赖于IDisposable
,而不是Finalize
,并假设客户端代码将使用块正确使用)
饥饿
删除对线程优先级的任何修改。正确的优先级划分实际上有点违反直觉:最好是给工作最多的线程分配较低的优先级,给受I/O限制的线程(包括UI线程)分配较高的优先级。由于Windows会自动执行此操作(请参阅),因此根本没有理由让代码参与其中
一般来说
删除所有内部编写的无锁代码。它几乎肯定包含一些微妙的错误。将其替换为.NET 4和,或将代码更改为基于锁
使用更高级的概念进行同步。NET 4中的和几乎不需要直接使用ManualResetEvent
,监视器
,信号灯
,等等
使用更高级的概念进行并行化。NET 4具有内置的自平衡算法,并配有智能分区和窃取工作队列,以自动提供最佳并行化。对于自动并行是次优的少数情况,TPL和PLINQ都公开了大量可调整的旋钮(自定义分区方案、长时间运行的操作标志等)
我发现还有一种技术对任何类都很有用,它的方法由不同的线程调用:记录哪些方法在哪些线程上运行。通常,这会作为注释添加到方法的顶部。确保每个方法仅在已知线程上下文中运行(例如,“在UI线程上”或“在线程池线程上”或“在专用后台线程上”)。除非您正在编写一个同步类(如果您正在编写一个同步类,请自问是否真的应该这样做),否则这些方法都不应该说“在任何线程上”
最后,命名你的线程。这有助于在使用VS调试器时轻松区分它们。NET通过Thread.Name
属性支持这一点。我认为任何技术都不能可靠地检测所有多线程问题,因为导致这些问题的代码太复杂,无法分析。没有任何工具能够实时检测此类问题,因为工具本身也需要时间来运行。要调试的程序在使用该工具和不使用该工具时的行为完全不同
我必须调试生产中每月只发生一次的实时问题!我找到的唯一解决方案是添加检测该问题的代码,并通过相关线程编写跟踪信息。当然,跟踪必须非常快速且无阻塞。Visual Studio等常用工具对于实时跟踪来说速度太慢,但幸运的是,编写自己的内存跟踪非常容易:
const int maxMessages = 0x100;
const int indexMask = maxMessages-1;
string[] messages = new string[maxMessages];
int messagesIndex = -1;
public void Trace(string message) {
int thisIndex = Interlocked.Increment(ref messagesIndex) & indexMask;
messages[thisIndex] = message;
}
此方法还收集线程和计时信息并输出跟踪信息,其更详细的描述如下:
CodeProject:实时调试多线程代码+1以便。。。令人敬畏。根本不知道有这样的事存在!国际象棋万岁!从理论上讲,这是非常棒的,但我个人在实践中并没有太多的运气。它只是没有检测到我试图诊断现有MT问题的问题,所以它几乎失败了。这现在是VS2010的一部分,不是吗?据我所知,VS2010包含了用于并行调试的新工具/功能,但我不知道是否包括Chess或Chess的子集。有很多很酷的工具,但是不要忽略阅读代码的简单方法。多年来我一直在进行多线程调试,这是最有效的方法之一。这很有效。我更多地关注的是技术(“像这样”)而不是工具。+1@Stephen确实如此。