确定持有文件锁的线程

Posted

技术标签:

【中文标题】确定持有文件锁的线程【英文标题】:Determine thread which holds the lock on file 【发布时间】:2009-11-10 18:53:27 【问题描述】:

我知道没有 WINAPI 可以做到这一点,但是如果一个线程被挂起并持有一个打开的文件句柄。我们如何确定线程 ID 并在我们的进程中终止它。

我说的不是在其他进程中释放文件锁,而是在我自己的进程中。

也有可能线程在没有关闭句柄的情况下崩溃/终止。

【问题讨论】:

在某些情况下或每次文件处理过程中线程是否阻塞? 在某些情况下是这样,但是在单独的区域中我必须删除该文件,但是由于我知道它自己的进程,所以它会出现拒绝访问错误,如果我能弄清楚线程,我可以终止它或关闭句柄,甚至找出调试哪个线程以及为什么.. 你永远不应该调用 TerminateThread,见***.com/questions/1004676/…。 视情况而定。例如,如果您使用互斥锁,则所有权转移。虽然我同意它通常不安全,但我认为永远不是正确的说法。 @SnapConfig - 如果你能保证线程在你控制的代码中执行并且它的终止不会有副作用,你就可以安全地杀死一个线程。如果它位于库或操作系统提供的任何代码中,则无法可靠地终止它。唯一明确的安全情况是线程被创建为挂起并且尚未开始运行。 【参考方案1】:

您无法确定哪个线程拥有文件的打开句柄。几乎所有的内核句柄,包括文件句柄,都不与线程相关联,而只与进程相关联(互斥锁是一个例外 - 它们有一个拥有线程的概念。)

假设我有以下代码。哪个线程“拥有”文件句柄?

void FuncCalledOnThread1()

     HANDLE file = CreateFile(...);

     // Hand off to a background thread.
     PostWorkItemToOtherThread(FuncCalledOnThread2, file);


void FuncCalledOnThread2(HANDLE file)

       DoSomethingWithFile(file);
       CloseHandle(file);

【讨论】:

好点。尽管我确实找到了一些枚举句柄的来源,仅供其他人参考。 forum.sysinternals.com/forum_posts.asp?TID=18892【参考方案2】:

使用进程资源管理器 - http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx [编辑或处理-http://technet.microsoft.com/en-us/sysinternals/bb896655.aspx]

【讨论】:

我认为他想以编程方式进行。 啊,好的。不知道,对不起。【参考方案3】:

当发生这种情况时,您可以使用调试器附加到进程,暂停程序,搜索导致这种情况的线程,然后遍历堆栈,找出它在做什么,它执行了哪些代码,以及哪些变量在堆栈。

如果您使用 RAII 进行锁定,这应该足够了,因为锁必须在堆栈上。

【讨论】:

我不能在他们不允许我们调试的客户机器上使用它。 :(.. aaaah RAII 10 年编写的 150 万行代码 :).. 我只是在修复它.. 你是个英雄。我曾经在一个 MLoC C++ 项目中工作过,该项目的内核也有 10 年的历史。但即使在最古老的部分(在较新的部分也很好),这也是不错的 C++。无论如何,我发现 MT 错误的唯一方法是记录、记录和记录。【参考方案4】:

我没有看到任何浏览 MSDN 的内容,尽管肯定有一些可能没有记录的内容可以为您提供所需的信息。

如果您的线程正在创建这些资源,并且预计其中一个线程可能会出去吃午饭,那么让他们从一个专门负责创建和处置资源的实用线程查询资源是否更有意义?这样的线程不太可能崩溃,而且在发生崩溃的情况下,您始终知道资源线程实际上是这些句柄的所有者。

【讨论】:

以上是关于确定持有文件锁的线程的主要内容,如果未能解决你的问题,请参考以下文章

Java:线程在没有获取锁的情况下持有锁

MySQL找出锁等待

MySQL找出锁等待

MySQL找出锁等待

自旋锁原理及java自旋锁

锁volatileCAS的比较