2012-06-22 83 views
1

我们有一个多线程应用程序。为了记录目的,其中一个工作线程调用GetModuleFilename,并且我们已经看到工作线程在调用永远阻塞的GetModuleFilename之前持有锁的死锁。什么可能getmodulefilename阻止?

我们可以并且已经从这个锁中删除了GetModuleFilename调用,但仍然非常关心死锁的发生。

做一些阅读在线: http://blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx

似乎GetModuleFilename将收购loaderlock,这似乎是一个不错的人选了僵局。

但loaderlock中的线程通常不会执行我们自己的任何代码,除了在dllmain中,根据上面的链接。

dll_thread_attach或detach可能会在loaderlock和另一个正在创建或销毁的workerthread中被调用,但我没有看到任何方式尝试获取我们正在使用的锁。

主线程也可能尝试获取GetModuleFilename线程所持有的锁,第三个线程持有loaderlock并执行sendmessage或类似于主线程上的阻塞操作?在这里,我还没有发现任何情况下会发生这种情况。

我怀疑其中的一个线程是使用com对象的线程之一。该线程在开始时调用coinitialize,因此应该位于单线程的公寓中。在这里与loaderlock交互的任何可能性?

反正我们还没有能够确定发生这种僵局的确切方式。所以我希望有一些想法,或者就其他情况而言,关于加载程序锁的更多信息是否已被获取,以及是否有任何其他代码将在加载程序锁中执行并有可能阻止的情况。

谢谢。

回答

0

好了,原来我所描述的问题仅仅是一个不同的问题,在我们使用的库的症状。该库显然在两个不同的线程中使用了一些wininet apis,其中一个在dllmain中,在loaderlock中。这两个线程死锁,随后锁定我们称为GetModuleFileName的线程。

这就像我现在所知道的一样多,但是一旦我们从图书馆的供应商那里获得更多的细节信息,我就会更新它。

0

只是一些随机的想法:

  • 如果有C++(而不仅仅是C)的代码,它是当系统持有的负载锁也被执行DLL的静态分配对象的可能构造。你不用在任何地方在这个对象的构造函数/析构函数中使用你的锁吗?

  • 也许这个错误可能会在那里,尽管你的锁,并使用锁实际上可能只是“取消隐藏”改变某些线程中某些时间的动作。 DllMain()和线程可能会很棘手。见http://blogs.msdn.com/b/oldnewthing/archive/2007/09/04/4731478.aspx

+0

感谢您的想法,花了一些时间来思考它们:为了使锁成为dll的一个因素,应用程序必须将该特定实例传递给dll,这应该很容易找到。没有看到这样的事情。锁似乎是涉及到的,因为当我能够重现问题时,移除锁似乎会导致死锁消失。但永远不能排除改变时机。我还编辑了问题描述,以包含一个使用com对象的线程,当我遇到这种情况时,com对象总是出现在那里。 –

+0

错误的链接,使用这一个:http://blogs.msdn.com/b/oldnewthing/archive/2004/01/28/63880.aspx –

+0

那一个已经在问题中,显然没有帮助。但是有很多方法可以使用'DllMain()'导致死锁,我的链接也提供了一些。 – mity

相关问题