TLS Callbacks

id:NyaRuRu:20051220#p2 続編.

Windows Server 2003以降(これにはWindows XP Professional x64 Editionも含まれる)のOSでは、FlsAllocを使用することで、ファイバ終了時にOSからコールバックを受けることができるようになりました。ファイバローカルストレージ(FLS)は、ファイバを全く使用しない場合でもTLSの代用として使用できます。そのためVisual C++ .NET 2003のCRTやVisual C++ 2005のCRTは、可能であればファイバローカルストレージを利用することで、確実に管理ブロックを開放するようになっています。このような重要なコールバックメカニズムが、従来のTLSには欠如していたと言えるでしょう。

ごめんなさい,Win32 Thread Local Storage (TLS) にコールバックメカニズムは存在して,google:"TLS Callbacks" というのがあるようです*1
TLS Callbacks は PE ヘッダ中にコールバック関数を登録しておくことで EXE ファイルでも DllMain 相当の通知を受けられるというものです.
http://www.interq.or.jp/chubu/r6/reasm/PE_FORMAT/6_6_2.html
Windows 2000Windows XP では以下のコードを付け足すことでサンプルプログラムでもメモリリークが発生しなくなることを確認しました.

namespace 
{ 
    extern "C" void __cdecl _freeptd (void *);
    void NTAPI tls_callback( void*, DWORD dwReason, void* ) 
    { 
        if(dwReason == DLL_THREAD_DETACH) 
        {
            _freeptd(NULL);
        }
    } 

    // Add callback to the TLS callback list in TLS directory.
    #pragma data_seg(push, old_seg)
    #pragma data_seg(".CRT$XLB")
    DWORD tls_callback_ptr = (DWORD)tls_callback;
    #pragma data_seg(pop, old_seg)

    extern "C" int _tls_used;
    int dummy() {
        return _tls_used;
    }
}

また Windows 98 SE で TLS Callbacks が呼び出されないことを確認しました.

Thread-Local-Storage Callbacks are a seldom used feature of Portable Executables. Many compilers and linkers, including Microsoft's, do not fully support TLS callbacks, or have a buggy implementation. Furthermore, they are not universally supported on all Windows platforms. Win9x does not execute them under all conditions (i.e. program load), while WinNT does.

とあるように,Windows 9x では TLS Callbacks はサポートされていないようです.
CodeZine の記事は月曜にでも訂正入れておきます.

*1:TLS Callbacks の存在については boost ML の「Windows MSVC thread exit handler for staticly linked Boost.Thread」での議論で知りました.このあたりは正直 Advanced Windows でも足りてない感じです.

Concurrent と Parallel

『Kazzzの「JとNの狭間で」』より.id:Kazzz:20060119#p2 に続編.

両方とも、並行とか、並列などの意味として使われる言葉だが、違いはなんなのだろう。

id:NyaRuRu:20050316#p4 で紹介した @IT の記事がコンカレントとパラレル(「並行」と「並列」)を使い分けてましたね.
.NETマルチスレッド・プログラミング入門
ちなみに個人的な印象ではこんな感じです.

Concurrent
処理順序の変更やインクリメンタル実行が可能なこと.(副作用がないといいなぁと思いつつ一般には妥協しまくりかもしれない)
Parallel
(タイミングを意識して)同時に実行すること

ただ研究者の間で一般的にどう使い分けられるかは知らないので,今度大学の先輩にでも聞いておきます.

Thread Abort and High Availability

引き続き『Kazzzの「JとNの狭間で」』より.

一般的な、Javaサーブレットコンテナは、上がってくるHTTPリクエストに対して生のスレッド、又はスレッドプールからのスレッド(以降Webスレッド)を割り当てて、serviceを起動していく実装になっていると思うが、この時にWebスレッドの処理がシステムから見て、我慢できない程に時間が掛っていたり、負荷が高かったりしていることを検知して、Webスレッドで実行されている処理を異常終了させる、標準的な方法って無いんだろうか。

さすが、トランザクションモニタの雄Tuxedoをだしてるベンダだしな、と納得した。しかし、実行スレッドの「スタック状態」を検出するところは、もろ期待通りなのだが、サーバ全体のステータスを変えるというのはちょっと違う。スレッドがスタックしたことを一定の閾値で検出したならば、そのスレッドのみを殺して欲しいのだ。

この機能、特にJavaのようにスレッドプールを多用しているサーバでは非常に重要だと思うのだが、そうではないのだろうか。

.NET 界隈の話としては,以前 arton さんのところでちょこっと書いたこの辺かな.
http://arton.no-ip.info/diary/20051207.html#c01
以下の MSDN の記事 (上が邦訳で下が原文) が秀逸.

.NET Framework の信頼性機能でコードを実行し続ける
https://www.microsoft.com/japan/msdn/msdnmag/issues/05/10/Reliability/default.aspx
Keep Your Code Running with the Reliability Features of the .NET Framework
http://msdn.microsoft.com/msdnmag/issues/05/10/Reliability/

この中で出てきているユースケースはこんな感じでしょうか.

  • ここで非同期例外が発生した場合の回復処理が大変なんだけど,非同期例外の発生箇所を事前か事後に移動できないかな?
  • この処理を実行中のスレッドをアボートしちゃうと明らかにプロセス全体がクラッシュするんだけど,それをシステムに伝えられない?
  • このアンマネージドリソースは例えスレッドがアボートされてもリークしたらまずいんだけど,どうしたら確実に解放できるかな?
  • スレッドアボートを指示して 5 秒待っても終了処理が完了しなければ問題を格上げしたいんだけど出来る?