我们有一个支持二进制插件(动态加载库)的应用程序以及一些此应用程序的插件。该应用程序本身是多线程的,插件也可能启动线程。有很多锁定正在进行,以保持数据结构的一致性。多线程环境中的文档锁定
一个主要问题是,有时锁从应用程序调用到插件中。这是有问题的,因为插件代码可能要回调到应用程序中,导致死锁。由于不同的团队在基本应用程序和插件上工作,这个问题更加严重。
问题是:除了编写大量的纯文本之外,是否存在“标准”或至少广泛使用的记录锁定方案的方式?
我们有一个支持二进制插件(动态加载库)的应用程序以及一些此应用程序的插件。该应用程序本身是多线程的,插件也可能启动线程。有很多锁定正在进行,以保持数据结构的一致性。多线程环境中的文档锁定
一个主要问题是,有时锁从应用程序调用到插件中。这是有问题的,因为插件代码可能要回调到应用程序中,导致死锁。由于不同的团队在基本应用程序和插件上工作,这个问题更加严重。
问题是:除了编写大量的纯文本之外,是否存在“标准”或至少广泛使用的记录锁定方案的方式?
这是一个理论方法,我希望它能帮助你一点。
对我来说,通过重新设计插件和应用程序通信的方式(如果可能),可以避免这种情况。
插件的代码不安全。为确保应用程序的灵活性和稳定性,您必须构建一种标准方式来交换信息并通过插件进行关键操作。
最简单的方法是避免通过定义无锁api来管理每个特定的插件行为。 要做到这一点,您可以使用环形缓冲区/干扰程序或只是一个动作缓冲区,使插件的关键部分异步。
编辑
很抱歉,如果我以同样的方式再次争论,但这似乎对我来说就像一个“IO”的问题。
对某些资源(内存/磁盘/网络....不知道哪些资源)以及是否需要以高可用性对其进行公开访问。最后,这些资源无法在未锁定您的应用程序的情况下随机访问。
由于经理致力于关键部件,所以等待时间可以足够短以致不可察觉。
但是,这并不容易适用于已经存在的应用程序,大多数情况下,如果它是一个大的应用程序。
如果你还不知道这种东西,我鼓励你看看“干扰者”。对我而言,每次使用线程时都要考虑现代基础知识之一。
嗯,这本身就是一个很好的方法,但是无锁是不可行的,因为从插件返回到主应用程序的有问题的调用主要是查询插件不能等待的信息。 – arne
我建议使用简单易学的Petri网,并且可以很好地描述软件不同部分之间的合作。在这个问题中描述了几个有用的文件并发性的模型和工具:https://stackoverflow.com/questions/164187/what-tools-diagrams-do-you-use-for-modelling-multithreaded-systems。您可以根据需要选择合适的型号。
这似乎是最好的方法,但我担心为软件系统写下Petri网将会相当混乱。 – arne
我知道,不幸的是每个模型都有一些优点和缺点。 我的建议是限制使用Petri Net来描述对共享资源的访问,或者一般来说描述生产者 - 消费者之类的合作。为了描述线程之间的同步,您可以使用UML活动图,它非常好,易于理解。 –
如果您的锁定方案足够简单以至于您可以在文档中描述它,那么通过所有方式都可以这样做。但是,如果在实践中发生死锁,问题可能不是缺少文档,但API不能满足插件作者的需求。记录限制是一个好的第一步,但消除这些限制会更好。
考虑对你的代码举行,由插件请求一个锁死锁的可能性:
这是最好的建议,我可以在不了解任何关于您的应用程序及其特定需求的更多信息。
对于大多数应用程序,软件公司在相同的过程中回避第三方二进制插件,因为当出现问题时,很难找出原因。用户通常责怪应用程序,而不是插件,并且对应用程序质量的看法很差。可以通过与插件作者保持非常密切的关系来工作,通常包括交换所有源代码(可选地在限制性许可证或NDA下)。
尽管这并没有回答这个问题(我明确地询问了文档工具/技术),但它仍然考虑了一些优点。感谢您的洞察力。 – arne
是的,有一个标准的方式来记录在大学使用的锁定方案。 1 /使用图表 您必须绘制图表。图中的每个点都是到其他线程的锁定链接。
ex: T1 T2
1 -R-> A
2 <-W- B
2 /使用表 你必须在每个点和线写在每一行
ex: T1 T2
lockX(A) lockS(B)
read(A) read(B)
A<-A50 unlock(B)
的结论是:这是非常复杂的任务,需要很多时间来追查。
简单但可能相当有效。 – arne
语言??????? – Ricibob
英文?不,严重的是,我会对描述锁定的语言不可知的方式最感兴趣。如果您有针对特定语言的解决方案,请开火。 – arne
递归锁呢?找到一个可以被同一个线程多次锁定的互斥锁。 – 2014-03-25 17:19:26