Multithreading 多线程分析技术

Multithreading 多线程分析技术,multithreading,analysis,Multithreading,Analysis,有人知道可以用来设计/调试线程锁定和解锁序列的任何分析技术吗?本质上是一种技术(比如真值表),我可以用它来证明我的锁序列不会死锁 这不是那种通过尝试和错误编程可以很好地解决的问题 我的特殊问题是读写锁——但我问的是一般意义上的问题。我相信这将是一个有用的技术,以了解是否存在 我尝试了一个因果图,其中有方框和箭头,可以用来跟踪控制流程,解决了80%的问题。但在压力测试中,当一个线程通过“指令之间的间隙”时,我仍然会偶尔遇到死锁,如果这有任何意义的话 总结;我需要的是某种表示问题的方法,以便正式分析

有人知道可以用来设计/调试线程锁定和解锁序列的任何分析技术吗?本质上是一种技术(比如真值表),我可以用它来证明我的锁序列不会死锁

这不是那种通过尝试和错误编程可以很好地解决的问题

我的特殊问题是读写锁——但我问的是一般意义上的问题。我相信这将是一个有用的技术,以了解是否存在

我尝试了一个因果图,其中有方框和箭头,可以用来跟踪控制流程,解决了80%的问题。但在压力测试中,当一个线程通过“指令之间的间隙”时,我仍然会偶尔遇到死锁,如果这有任何意义的话


总结;我需要的是某种表示问题的方法,以便正式分析互斥锁的重叠。

恐怕是坏消息。据我所知,没有任何技术可以“证明”一个使用锁来控制对共享内存的访问的系统。我所说的“证明”是指你不能从分析上证明程序不会死锁、活锁等

问题在于线程是异步运行的。一旦您开始拥有合理数量的线程和共享资源,可能的事件序列(例如锁定/解锁共享资源)的数量就高得惊人,您无法对它们中的每一个进行建模/分析

因此,早在1978年,Tony Hoare就开发了通信顺序过程。这是演员模型的发展,演员模型本身对解决这个问题有很大帮助

演员和CSP

简而言之,在Actor模型中,数据不是通过带有锁的共享内存进行通信的。相反,副本通过两个线程之间的某种通信通道(例如套接字或管道)发送。这意味着您永远不会锁定内存。实际上,所有内存对线程都是私有的,并且在需要时将其副本发送给其他线程。这是一个非常“面向对象”的东西;私有数据(线程拥有的内存)、公共接口(在通信通道上发出和接收的消息)。它还具有很强的可伸缩性——管道可以成为套接字,线程可以成为其他计算机上的进程

CSP模型与此类似,只是通信信道不会接受消息,除非接收端准备好读取它

这个加法是至关重要的——它意味着系统设计可以用代数方法进行分析。事实上,Tony Hoare为CSP制定了一个流程计算。CSP的维基百科页面引用了这一点来证明电子商务系统的设计

因此,如果一个人正在开发一个严格的CSP系统,就有可能通过分析证明它不会死锁,等等

真实世界体验

我做过很多CSP(或CSP-ish)系统,它一直都很好。我没有做数学,而是用直觉来帮助我避免问题。实际上,CSP确保了,如果我构建了一个可以死锁的系统,它每次都会死锁。所以,至少我在开发中发现了它,而不是2年后,当一些网络连接变得比正常情况更繁忙时

真实世界选项

对于演员模型编程,有很多选择。ZeroMQ、nanomsg、Microsoft的.NET数据流库

它们都很好,只要小心,你就能制作出一个非常好的系统。我非常喜欢ZeroMQ和nanomsg——它们使得在不同的计算机上将一堆线程分割成不同的进程变得非常简单,而且您根本没有改变体系结构。如果绝对性能不是必需的,那么将这两者结合起来,例如,Google Protocol Buffers将成为一个非常整洁的系统,它提供了大量选项,可以将不同的操作系统、语言和系统合并到您的设计中

我怀疑MS的.NET数据流库会移动数据引用的所有者,而不是复制数据。这应该会让它表现得相当出色(尽管我实际上还没有试过看)

CSP有点难搞。通过设置消息缓冲区长度,您几乎可以使ZeroMQ和数据流进入CSP。不幸的是,您不能将缓冲区长度设置为零(这将使其成为CSP)。MS的文档甚至讨论了将队列长度设置为1对系统健壮性的好处

您可以在Actor之上合成CSP,方法是在链接之间有同步消息流。这是烦人的必须实施

我经常构建自己的comms框架来获得CSP环境

我认为有一些Java库,不知道它们开发得有多积极

然而,由于现有代码是围绕锁定的共享内存编写的,因此修改代码将是一项艰巨的工作。所以

内核鲨鱼

如果您在Linux上,并且您的内核已经编译了FTRACE,那么您可以使用kernelshark查看系统中发生了什么。与Solaris上的DTRACE、VxWorks上的WindView和MCOS上的TATL类似

你要做的是运行你的系统,直到它停止,然后很快保存FTRACE日志(它会被操作系统在循环缓冲区中覆盖)。然后,您可以图形化地看到发生了什么(打开kernelshark的进程视图),这可能会提供关于什么做了什么以及什么时候做了什么的线索

这有助于您诊断应用程序的死锁,这可能会导致您将事情做对,但最终您永远无法证明这样做是正确的。这并不能阻止你拥有一个你现在骨子里知道你做对了的尤里卡时刻


据我所知,Windows上没有类似的FTRACE/Kernel shark。

对于范围广泛的多线程任务,我们可以绘制一个反映资源锁定顺序的图表。如果这个图有循环,这意味着死锁是很有可能的。如果没有循环,死锁永远不会发生