【问题标题】:Interrupting native threads中断本机线程
【发布时间】:2026-01-21 12:50:02
【问题描述】:

我目前正在研究 Thread.Interrupt 如何与 P/Invoke 或本机调用一起使用。我在 MSDN 中读到不可能中止(Thread.Abort)本机调用中的线程(其他用例也可能适用)。但是我没有找到任何引用说明处于 WaitSleepJoin 状态的本机线程的状态相同。

这个问题不是关于应该调用 Abort 还是 Interrupt,而是关于我在哪里可以找到关于此的权威文档。对此的 G-ing 没有提供任何有用的输出。

我的测试示例:

#ifdef NATIVEFUNCTIONS_EXPORTS
#define NATIVEFUNCTIONS_API __declspec(dllexport)
#else
#define NATIVEFUNCTIONS_API __declspec(dllimport)
#endif

#include <iostream>

extern "C"
{
  NATIVEFUNCTIONS_API void EndlessWait(char const* mutexName)
  {
    std::cout << "entering the endless wait." << std::endl;

    HANDLE mutex = CreateMutex(NULL, FALSE, mutexName);
    WaitForSingleObject(mutex, INFINITE);

    std::cout << "leaving the endless wait." << std::endl;
  }

};

本机 C++-DLL 导出函数,无休止地等待互斥体。

现在是 C# .NET 对应项,它试图取消等待:

using System;
using System.Threading;
using System.Runtime.InteropServices;

namespace InterruptingNativeWaitingThread
{
  class Program
  {
    [DllImport("NativeFunctions.dll", CharSet=CharSet.Ansi)]
    static extern void EndlessWait(string str);

    static void Main(string[] args)
    {
      string mutexName = "interprocess_mutex";
      Mutex m = new Mutex(false, mutexName);
      m.WaitOne();
      Thread t = new Thread(() => { EndlessWait(mutexName); });
      t.Start();
      Thread.Sleep(1000);

      t.Abort();
      if(!t.Join(5000))
        Console.WriteLine("Unable to terminate native thread.");

      t.Interrupt();
      if(!t.Join(5000))
        Console.WriteLine("Unable to interrupt the native wait.");

      Console.WriteLine("Release the mutex.");
      m.ReleaseMutex();
      t.Join();
    }
  }
}

执行此应用程序会产生以下输出:

entering the endless wait.
Unable to terminate native thread.
Unable to interrupt the native wait.
Release the mutex.
leaving the endless wait.

Abort 在此上下文中无法按预期工作,但 msdn 没有提及中断。我希望它一方面可以工作:因为处于等待状态的托管线程也调用本机 WaitForSingleObject 或 WaitForMultipleObjects;另一方面,有可能被中断的本机线程不支持所有期望异常,还有什么?

非常欢迎任何文档!

非常感谢,
风向标

附:我还在MSDN 中发现,abort 会等待要中止的线程从非托管代码返回,如果线程处于 WaitSleepJoin 状态,则首先调用中断然后中止它。但这并不意味着中断不能中断原生的 WaitSleepJoin。

【问题讨论】:

    标签: c# .net multithreading pinvoke native


    【解决方案1】:

    我怀疑线程处于 WaitSleepJoin 状态;中断被记录为仅在此状态下中断线程。查看线程的 ThreadState 属性来验证它处于什么状态。

    【讨论】:

    • 确实,线程处于运行状态。似乎.NET 有自己的线程状态管理。在调用 t.Abort() 之后,线程处于 AbortRequested 状态,但 Thread.Interrupt 不会中断它,因为它从未处于 WaitSleepJoin 状态。非常感谢!