2007-05-04

プロセス終了時にメモリを解放すべからず

http://blogs.msdn.com/oldnewthing/archive/2007/05/03/2383346.aspx  よく、OSが解放してくれるから、プロセス終了時にはリソース解放などをしなくてもいいという意見に対して、「いや、できる限りすべきだ」という人が居るが、場合によりけりということらしい。いや、別にしてもいいのだけれど、DLL_PROCESS_DETACHの中でやるなということで。  プロセスが終了するとき、Windows XPがどのような処理をするか。ExitProcessが呼ばれたとき、ExitProcessを読んだスレッド以外のすべてのスレッドは、終了される。スレッドが何をしていようがお構いなしだ。つまりは、TerminateThreadに等しいということだ。MSDNではTerminateThreadは使うべきではないとしつこく警告されているが、一体何がまずいのか。実は、TerminateThreadとは、スレッドが何をしていようと、強制的に終了させるのだ。もし、強制終了されるスレッドが、クリティカルセクションに入っていた場合、そのクリティカルセクションはロックされたままになる。これの何がまずいのかというと、スレッド間で排他をとるヒープを使っていて、まさにヒープからメモリを確保、解放するときに終了されると、ヒープがロックされたままになる。  さて、ある「賢い」DLLは、DLL_PROCESS_DETACH通知が送られたときに、確保したリソースを解放しようとする。しかし、そのリソースに排他的にアクセス中のスレッドが強制終了された場合、リソースを解放しようとすると、例外を投げてこける。結果的にプロセスは終了するのだが、なんとも汚い終わり方になってしまう。  そこで、プロセス終了時のDLL_PROCESS_DETACHの中では、何もするな。何も「賢い」ことをするな。ただreturnせよ。リソースの解放はOSにまかせろ。  ただし、動的にDLLがアンロードされる場合は、この限りではない。まだプロセスは動き続けるのだから、リソースを解放しなければ、リソースリークになってしまう。なんともやっかいだ。

No comments: