代码之家  ›  专栏  ›  技术社区  ›  Canopus

如何将名称设置为Win32线程?

  •  17
  • Canopus  · 技术社区  · 15 年前

    如何设置Win32线程的名称。我找不到任何win32 API来实现这一点。基本上我想在日志文件中添加线程名。TLS(线程本地存储)是唯一的方法吗?

    9 回复  |  直到 6 年前
        1
  •  0
  •   ralphtheninja    15 年前

    您始终可以将这些信息存储在适当的数据结构中。使用哈希或映射将getThreadID()映射到此名称。由于getthreadid()始终是唯一的标识符,所以它工作得很好。

    干杯!

    当然,如果他创造了很多 线程,该hashmap将慢慢填充 使用越来越多的内存,所以 某些清理过程可能是 这也是好事。

    你说得对。当一个线程死后,它在映射中的相应条目应该被自然删除。

        2
  •  31
  •   Gishu    15 年前

    这有帮助吗? How to: Set a Thread Name in Native Code

    在托管代码中,它与设置相应线程对象的名称属性一样简单。

        3
  •  20
  •   phyatt    11 年前

    http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.90).aspx

    //
    // Usage: SetThreadName (-1, "MainThread");
    //
    #include <windows.h>
    const DWORD MS_VC_EXCEPTION=0x406D1388;
    
    #pragma pack(push,8)
    typedef struct tagTHREADNAME_INFO
    {
       DWORD dwType; // Must be 0x1000.
       LPCSTR szName; // Pointer to name (in user addr space).
       DWORD dwThreadID; // Thread ID (-1=caller thread).
      DWORD dwFlags; // Reserved for future use, must be zero.
    } THREADNAME_INFO;
    #pragma pack(pop)
    
    void SetThreadName( DWORD dwThreadID, char* threadName)
    {
       THREADNAME_INFO info;
       info.dwType = 0x1000;
       info.szName = threadName;
       info.dwThreadID = dwThreadID;
       info.dwFlags = 0;
    
       __try
       {
          RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR),       (ULONG_PTR*)&info );
      }
      __except(EXCEPTION_EXECUTE_HANDLER)
      {
      }
    }
    
        4
  •  10
  •   David Heffernan    11 年前

    Win32线程没有名称。有一种微软的惯例,即应用程序引发包含线程名的特殊SEH异常。这些异常可以被调试程序截获并用于指示线程名。有几个答案可以说明这一点。

    但是,所有这些都由调试器处理。线程本身是无名对象。因此,如果您想将名称与线程关联,就必须开发自己的机制。虽然您可以使用线程本地存储,但它只允许您从该线程中执行的代码中获取名称。因此,线程ID和名称之间的全局映射似乎是最自然和最有用的方法。

        5
  •  4
  •   Community CDub    7 年前

    可以使用线程本地存储对象来存储名称。例如,

    __declspec( thread ) char threadName[32];
    

    然后你可以从一个线程中读写这个。这在记录器应用程序中可能很有用,在该应用程序中,您希望打印出每个消息的线程名称。您可能希望在线程启动时立即编写此变量,并引发Microsoft异常( https://stackoverflow.com/a/10364541/364818 )以便调试器也知道线程名。

        6
  •  3
  •   Chris Kline    7 年前

    根据与微软调试团队领导的讨论(详情请参见下面的链接),sethreaddescription api是微软未来将使用的API,以支持在本机代码中正式命名线程。我所说的“正式”是指用于命名线程的MS支持的API,而不是当前的异常引发的hack,它目前只在Visual Studio中运行进程时工作。

    此API从1607版Windows10开始提供。

    但是,目前对工具的支持非常少,因此您设置的名称在Visual Studio或windbg调试器中不可见。但是,截至2017年4月,Microsoft Xperf/WPA工具确实支持它(通过此API命名的线程的名称将正确显示在这些工具中)。

    如果您希望看到此功能获得更好的支持,例如在windbg、Visual Studio和崩溃转储文件中,请使用以下链接投票:

    https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/17608120-properly-support-native-thread-naming-via-the-sett

        7
  •  1
  •   selbie    15 年前

    如果要在调试器(windbg或Visual Studio)中查看线程的名称: http://blogs.msdn.com/stevejs/archive/2005/12/19/505815.aspx

    我不确定是否有相反的方法来获取线程名。但是,tls听起来像是一条路要走。

        8
  •  1
  •   Chris Kline    10 年前

    另一种方法是在线程teb的arbitraryuserpointer字段中存储指向该名称的指针。这可以在运行时写入和读取。

    有一篇题为 "Debugging With The Thread Information Block" 这向你展示了如何做到这一点。

        9
  •  0
  •   Marcos Marin    6 年前

    如果应用程序在Windows 1607+版本上运行,则可以使用 SetThreadDescription ()