我正在修复代码中的错误,并以最好的方式解决问题。以下是这种死锁的发生方式:
SendMessage
到GUI线程,因此阻塞。被锁定的资源是一个关于网络状态的大数据结构 - 包括用户列表,他们的个人资料信息等。
不幸的是,避免SendMessage
电话是不现实的。这对程序更改对GUI的异步影响太大了。
我的直觉是我的目标是避免在GUI线程中锁定。 GUI线程只需要对其锁定的数据进行读访问。这将解决此死锁,并可能修复应用程序中的其他响应时间问题。这是一种很好的直觉吗?
要做到这一点,我觉得GUI应该使用 copy 来访问它需要的数据,而不需要锁定任何东西。
所以,我如何获得此副本?如果我从GUI线程创建副本,那么我必须再次使用锁定,而我还没有解决任何问题。但我怎么能这样做呢?
或.......我的方法完全错了?修复此错误的最佳方法是什么?
修改:发现了一个类似的问题:EnterCriticalSection Deadlock
一些可能的解决方案:
PostMessage
。TryEnterCriticalSection
,如果我无法进入,则恢复邮件提取,然后再安排另一次尝试,可能使用PostMessage
。SendMessage
的呼叫的锁定。答案 0 :(得分:4)
使用PostMessage而不是SendMessage将避免死锁。有两种方法可以做到这一点。如果您不想复制数据,则GUI线程消息处理程序必须获取锁以访问数据。所以会有争用,但没有僵局。为了避免所有争用,您必须在工作线程中复制数据。使用' new'将副本放入堆中。然后将堆指针作为PostMessage调用的参数传递。 GUI线程可以访问数据副本,然后它应该删除传递的指针。
答案 1 :(得分:1)
GUI端的锁定保护是什么类型的操作?如果它仅用于显示,那么操作几十毫秒后就可能无关紧要了。
因此只能尝试获取互斥锁(例如TryEnterCriticalSection()
)而不是等待它,如果它不可用,请稍后重新安排更新(再次使窗口无效以触发另一个绘制消息,排队自定义更新消息或其他)。