繁体   English   中英

在流程终止时释放资源

[英]Deallocate resources on process termination

当进程被例如任务管理器杀死时,如何释放资源? 有没有办法在进程关闭之前调用函数?

如果你的进程被杀,你真的无能为力。 根据定义,杀死一个进程只是 - 杀死它。 该过程没有机会运行任何代码。 这非常“按设计”。

想象一下,您可以注册在您的进程被用户(或其他进程)杀死时调用的例程。 它会做什么? 您流程中的所有其他线程都处于不确定状态,您将如何与它们同步? 请记住,这个想法是需要杀死这个过程。

另一种情况甚至更加困难:你的代码是良性的,并且正在努力做正确的事情 - 例如清理并成为一名优秀的系统公民。 有些代码不是。 想象一下,如果操作系统允许为正在被杀死的进程运行代码,那将对恶意软件作者带来什么好处。 对于使用标准用户权限运行的恶意进程而言,这对于任何具有管理权限的运行来说都是非常糟糕的。

关键的最终结构和结构化异常处理不能解决这个基本问题。

从好的方面来说,操作系统将释放它在进程被终止时所知道的所有资源,即内存和内核对象。 那些不会泄漏。 但是资源管理器并不了解您的流程,因此无法清理它。

解决此问题的一种方法是建立一个监控流程来跟踪您的其他流程状态并清理它。 您可以通过简单的流程或服务来完成此操作。 你也可以考虑某种shell扩展,它有自己的线程做同样的事情。

在通过调用TerminateProcess (例如通过任务管理器或其他流程实用程序,如TSKILL或TASKKILL)即将终止的进程中终止时,无法执行任意代码。

既不是关键的终结器,也不是普通的终结器,也不是try / finally块,当然也不仅仅是实现IDisposable对象可能导致在这种情况下执行代码。 甚至DLL分离事件也不会通过TerminateProcess从进程终止中调用。

您可以做的最好的事情是使用监视程序进程监视原始进程并在原始进程终止时执行相关代码。

从理论上讲,O / S应该在进程被杀死后释放资源。 你特别想到什么样的资源?


编辑:

好的,解释起来有点棘手。 我正在使用一个包含一些OS函数的库来管理一些Shell Extensions。 当应用程序关闭但没有明确调用适当的方法时,所有资源管理器都会冻结,我需要重新启动它。

应该使用DLL_PROCESS_DETACH事件调用任何非托管DLL(根据文档); 但是,当通过TerminateProcess API终止进程时,不会调用此DLL_PROCESS_DETACH事件。

谷歌搜索这些术语出现旧的新事物:为什么你不能陷阱TerminateProcess? 其中说:“ 一旦你杀了TerminateProcess,就不会再有用户模式的代码在那个过程中运行。它已经消失了。

因为您尝试使用的所有内容(即.NET,Explorer,Shell,COM)都是在用户模式下进行的,所以我认为答案是没有办法做你想做的事情。

相反,也许还有另一种方法:例如,通过向Shell扩展添加代码,以便他们意识到您的流程是否被废弃。

您可以尝试将整个过程包装在try / finally语句中(将释放内容放在finally子句中),但在某些情况下即使这样也是不够的。

实际上,我认为你可以从你的进程中启动一个后台线程,用你的主线程做所有的东西和Thread.Join(),这样如果在子线程中出现问题,主线程仍然能够把事情弄清楚。 当然,如果由于某种原因整个过程终止,这将不起作用。

你也可以启动一个子进程并调用Process.WaitForExit(),但我不确定你的shell相关的东西是否可以使用多进程方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM