1
11
我不知道有一篇文章或一本书介绍了您要查找的内容,所以这里是我在Windows上进行12年多线程调试(非托管和托管)的“经验教训”。 正如我在评论中所说,我的大多数“多线程调试”实际上是通过手动代码检查来完成的,以查找这些问题。 死锁和损坏的共享状态 文件 lock hierarchies (秩序和他们保护的共享状态),并确保它们是一致的。这解决了大多数死锁问题和损坏的共享状态问题。 (注:“锁层次”的链接是指Herb Sutter的Dobbs博士文章,他写了一系列 Effective Concurrency 我强烈推荐的文章)。 更多关于死锁的内容 使用 RAII for all synchronization . 这样可以确保在出现异常时释放锁。最好使用“lock”语句来尝试/最终。
(注意,.NET中的raii取决于
饥饿 删除对线程优先级的任何修改。正确的优先级排序实际上有点违反直觉:最好给线程分配最大量的工作来做较低的优先级,并给I/O绑定的线程(包括UI线程)提供较高的优先级。因为Windows会自动执行此操作(请参见 Windows Internals )实际上根本没有理由让代码参与其中。 一般来说 删除内部编写的所有无锁代码。几乎可以肯定,它包含一些细微的错误。替换为.NET 4 lock-free collections 和 synchronization objects 或者将代码更改为基于锁的。
使用更高级的概念进行同步。这个
Task Parallel Library
和
unified cancellation
在.NET 4中,几乎不需要直接使用
使用更高级的概念进行并行化。这个 TPL and PLINQ 在.NET 4中,有内置的自平衡算法,包括智能分区和窃取工作队列,以自动提供最佳的并行化。对于少数情况下自动并行化是次优的,TPL和PLINQ都暴露了大量可调整的旋钮(自定义分区方案、长时间运行的操作标志等)。 我发现还有一种技术对任何类都有用,它的方法由不同的线程调用:记录哪些方法在哪些线程上运行。通常,这会作为注释添加到方法的顶部。确保每个方法只在已知的线程上下文中运行(例如,“在UI线程上”或“在线程池线程上”或“在专用后台线程上”)。任何方法都不应该说“在任何线程上”,除非您正在编写同步类(如果您正在编写同步类,请问问您自己是否真的应该这样做)。
最后,命名线程。这有助于在使用vs调试器时轻松区分它们。.NET通过
|
2
6
不是你要的,但也许你会发现 CHESS 有趣。 |
3
1
你也可以看看英特尔的 Thread Checker 或 Thread Profiler 和 Sun's Studio Thread Analyzer 尽管它们不是免费的。也签出 this 来自英特尔的文章。 |
4
0
我用了赫尔格里的一个子工具。Helgrind是一个线程错误检测器,我用它在我的一些代码中检测过一两次竞争条件。它可以检测到以下情况。
http://valgrind.org/docs/manual/hg-manual.html 显然,只有Linux工具用于系统程序,C/C++。没有Java或.NET。 |
5
0
我不认为任何技术都能可靠地检测到所有多线程问题,因为导致这些问题的代码太复杂,无法分析。任何工具都不能实时检测到这些问题,因为工具本身也需要时间来运行。要调试的程序在使用工具和不使用工具时的行为将完全不同。 我必须调试在生产中发生的实时问题,每月只有一次!我找到的唯一解决方案是添加代码检测该问题,并通过所涉及的线程写入跟踪信息。当然,跟踪必须非常快速且无阻塞。像Visual Studio这样的常用工具对于实时跟踪来说太慢了,但幸运的是,编写自己的内存跟踪很容易:
对于这种方法的更详细的描述是,它还收集线程和时间信息,并很好地输出跟踪信息,如下所示: 代码项目:实时调试多线程代码 1 |
SRobertJames · 使用printf的gdb显示 1 年前 |
Subin · 在vscode中运行c时出错 1 年前 |
Community wiki · 如何调试Python内存故障? 1 年前 |
Kai · 有什么方法可以轻松优化VSCode中的锈迹? 2 年前 |
Chris Brandon · 如何使节点在堆栈溢出时中断? 2 年前 |