TONT 38363 为什么有些进程在被中止后,仍然在进程管理器中显示着?

灵魂不灭论。

原文链接:https://devblogs.microsoft.com/oldnewthing/20040723-00/?p=38363

When a process ends (either of natural causes or due to something harsher like TerminateProcess), the user-mode part of the process is thrown away. But the kernel-mode part can’t go away until all drivers are finished with the thread, too.

当一个进程被中止时(不论是通过比较自然的方式,还是比较严厉的如 TerminateProcess(译注:原文链接已失效,此处为MSDN上对应的文章目前可用的链接) 的方式),其用户模式下的部分就被抛弃了,不过其内核部分在线程中的所有驱动结束操作前,是无法被移除的。

For example, if a thread was in the middle of an I/O operation, the kernel signals to the driver responsible for the I/O that the operation should be cancelled. If the driver is well-behaved, it cleans up the bookkeeping for the incomplete I/O and releases the thread.

例如,如果某个线程正处在一个 I/O 操作中,内核将通知该 I/O 操作对应的驱动取消该操作。倘若这个驱动运作正常的话,就应当对这个未完成的 I/O 操作进行清理,并最终释放对应的线程。

If the driver is not as well-behaved (or if the hardware that the driver is managing is acting up), it may take a long time for it to clean up the incomplete I/O. During that time, the driver holds that thread (and therefore the process that the thread belongs to) hostage.

但如果驱动运作不正常(或其所管辖的硬件出现了问题),可能就需要比较长的时间来清理这个未完成的 I/O 操作。在此期间,该驱动将持续保有相应的线程(该线程所属的进程亦然)。

(This is a simplification of what actually goes on. Commenter Skywing gave a more precise explanation, for those who like more precise explanations.)

(这是对类似事情发生时的情况的一个简化描述,访客 Skywing 撰写了一份更加准确的描述(译注:链接已失效,我们永远都无法再知道那天dalao说了些什么了),喜欢细节描述的人可以去看看。)

If you think your problem is a wedged driver, you can drop into the kernel debugger, find the process that is stuck and look at its threads to see why they aren’t exiting. You can use the !irp debugger command to view any pending IRPs to see what device is not completing.

如果你认为问题出在某个加楔而入的驱动上,你可以打开内核调试器,找到那个(关不掉的)进程,检视其线程列表来判断为什么它不肯退出,也可以在调试器中使用 !irp 命令来观察处于等待状态下的 IRP(译注:I/O Request Package,I/O 请求包),并由此判断是哪个设备没有完成其操作。

After all the drivers have acknowledged the death of the process, the “meat” of the process finally goes away. All that remains is the “process object”, which lingers until all handles to the process and all the threads in the process have been closed. (You did remember to CloseHandle the handles returned in the PROCESS_INFORMATION structure that you passed to the CreateProcess function, didn’t you?)

当所有的驱动得知某进程被中止的情况后,该进程的『肉体』才终于消失,而剩下的只是一个『进程对象』继续等待着,直到所有面向该进程的句柄及进程的所有线程都关闭位置。(你应该有记得把在调用 CreateProcess 时在 PROCESS_INFORMATION 结构中返回的句柄们用 CloseHandle 都关掉来着(译注:原文链接已失效,此处为目前MSDN上的新链接),没错吧?)

In other words, if a process hangs around after you’ve terminated it, it’s really dead, but its remnants will remain in the system until all drivers have cleaned up their process bookkeeping, and all open handles to the process have been closed.

换句话说,如果某个进程在被中止后仍然挂在那里,实际上这个进程的确已经被中止了,只是还有点小『残余』留在了系统中,直到所有相关的驱动完成了针对这个进程的清理工作,以及所有由该进程打开的句柄被关闭为止。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

 剩余字数 ( Characters available )

Your comment will be available after auditing.
您的评论将在通过审核后显示。

Please DO NOT add any links in your comment, otherwise it would be identified as SPAM automatically and never be audited.
请不要在评论中插入任何链接,否则将被自动归类为垃圾评论,且永远不会被提交给博主进行复审。

*