スレッドを調べまわって分かったことをメモ
こうですか?分かりません!><
WIN32のみのお話です。
スレッドって結構実装依存なのね…。
先にまとめ
- windowsは_beginthreadex推奨(CreateThreadはメモリリークの危険あり)
- _beginthread、_beginthreadexを呼び出すには、process.h をinclude
- _beginthreadexに入れられる関数ポインタは、__stdcall か __clrcall
- __stdcall は static WINAPI 〜
- __clrcall は CLR系なので今回は未調査
- 非staticなメンバメソッド(__thiscall)を呼び出すには、ラッパをかぶせる→staticでないクラスメンバ関数を_beginthreadで実行させる方法。 - かせいさんとこ
CreateThread
_beginthreadと、_beginthreadex
そもそもの違いは?
_beginthread | _beginthreadex | |
---|---|---|
呼出規約 | __cdecl or __clrcall | __stdcall or __clrcall |
Handleのクローズ | 終わったら勝手に閉じる | CloseHandleで明示的に閉じる必要あり |
エラー時の戻り値 | -1 | 0 |
停止した状態でスレッドを生成 | × | ○ |
スレッド識別子 | × | ○ |
子プロセスへの継承 | × | ○ |
どっちが良いの?
オフィシャルとしては、_beginthreadexを推奨
_beginthread よりも _beginthreadex を使用した方が安全です。
_beginthread によって生成されたスレッドの終了が早すぎると、_beginthread の呼び出し元に返されるハンドルが無効になる可能性や、別のスレッドを指す可能性があります。
しかし、_beginthreadex から返されるハンドルは _beginthreadex の呼び出し元で閉じられる必要があるため、_beginthreadex がエラーを返さなかった場合にはハンドルが有効であることが保証されます。
MSDN:_beginthread、_beginthreadex (CRT)
- _beginthreadは呼出先のメソッドが終了すると、勝手にハンドルを閉じます
- 呼出直後に終了するようなメソッドを呼で、ハンドルがあること前提の処理を親側に入れると危険
- 場合によっては、別のスレッドに影響が及ぶらしいです。
- 呼出直後に終了するようなメソッドを呼で、ハンドルがあること前提の処理を親側に入れると危険
- _beginthreadexは明示的にハンドルをCloseしなければならないので、忘れるとそれはそれでメモリリークの危険
呼出し規約について
- _beginthreadは、__cdecl
- _beginthreadexは、__stdcall
__cdecl
- 簡単に言えば、staticなメソッド
わかんなかったこと
- _beginthreadの存在理由がいまいち分からず。
- 勝手にハンドルを閉じてくれるのは便利ともいえるけど…。
- スレッド作りっぱなしで、その後、ハンドルを使って色々する気が無いなら、_beginthreadでも良いってこと?