簡體   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