4

我想检查进程的线程(整个进程)是否被挂起。我通过这段代码获取每个进程线程:

var threads = Proc.Threads;
for (int x = 0; x < threads.Count; x++) {
var thread = threads[x];

然而System.Diagnostics.ThreadState不包含Suspended,但包含System.Threading.ThreadState。我如何转换System.Diagnostics.ThreadStateSystem.Threading.ThreadState,或者是否有其他方法来检查它?我不是想暂停/恢复它们,只是想知道 Process hacker/Process explorer 是如何做到的。

4

4 回答 4

7

Microsoft 在 .NET 1.0 版中犯了一个大错误,他们添加了 Thread.Suspend() 和 Resume() 方法。这些方法被广泛滥用,程序员使用它们来实现线程同步。他们是完全不合适的。问题是它通常有效。但是在不走运的时候调用 Suspend(),当线程被隐藏在 Windows 调用中时,你会冻结一个线程,并持有一个全局锁。并导致整个程序死锁。

这不是他们犯的唯一设计错误,集合类上的 Synchronized 方法也是一场灾难。被广泛误解为“返回一个线程安全的集合”。

生活和学习,这一切都在 .NET 2.0 中得到了解决。一项重大改革是线程可能不再一定是操作系统线程,它从未真正实现过。但解释了为什么有两个ThreadState 枚举,一个用于 Thread(.NET 版本),另一个用于 ProcessThread(操作系统版本)。他们关闭了程序员滥用 Suspend/Resume 的漏洞,这些方法被宣布为过时。而且他们也关闭了后门,你无法从 ProcessThread 中查出一个线程被挂起。

功能,而不是错误。不要犯同样的错误,知道线程被挂起是无用的知识,它很可能在微秒后不再被挂起。

于 2013-08-16T08:47:44.573 回答
2

操作系统线程与 .Net 线程不同。Process.Threads 返回操作系统线程,每个线程可能对应也可能不对应 .Net 线程。

您可以查看 ProcessThread.WaitReason,但它不对应于 .Net 等待状态

于 2013-08-16T15:40:28.327 回答
2

这将帮助某人。

        Process proc = Process.GetProcessById(31448);
        if(proc.Threads[0].WaitReason == ThreadWaitReason.Suspended)
        {
            //process is suspended
        }
于 2021-01-04T17:59:48.447 回答
0

您可以不正确地使用SuspendThread或 Wow64SuspendThread 来确定它是否被挂起,然后使用ResumeThread来恢复情况。

SuspendThread return: "如果函数成功,则返回值为线程之前的挂起计数;"

声明:

    [Flags] public enum ThreadAccess : int {
        TERMINATE = (0x0001),
        SUSPEND_RESUME = (0x0002),
        GET_CONTEXT = (0x0008),
        SET_CONTEXT = (0x0010),
        SET_INFORMATION = (0x0020),
        QUERY_INFORMATION = (0x0040),
        SET_THREAD_TOKEN = (0x0080),
        IMPERSONATE = (0x0100),
        DIRECT_IMPERSONATION = (0x0200)}

    [DllImport("kernel32.dll")]
        static extern IntPtr OpenThread(
        ThreadAccess dwDesiredAccess,
        bool bInheritHandle,
        uint dwThreadId);

    [DllImport("kernel32.dll")]
        static extern uint SuspendThread(IntPtr hThread);

    [DllImport("kernel32.dll")]
        static extern int ResumeThread(IntPtr hThread);

    [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)] 
        static extern bool CloseHandle(IntPtr handle);

(Wow64SuspendThread 链接隐藏,因为我需要 10 个声誉来放置 2 个链接 = ht.tps://msdn.microsoft.com/it-it/library/windows/desktop/ms687400(v=vs.85).aspx)

于 2017-03-08T00:50:35.317 回答