2008-04-03
スレッドを調べまわって分かったことをメモ
こうですか?分かりません!><
WIN32のみのお話です。
スレッドって結構実装依存なのね…。
先にまとめ
- windowsは_beginthreadex推奨(CreateThreadはメモリリークの危険あり)
- _beginthread、_beginthreadexを呼び出すには、process.h をinclude
- _beginthreadexに入れられる関数ポインタは、__stdcall か __clrcall
- __stdcall は static WINAPI 〜
- __clrcall は CLR系なので今回は未調査
- 非staticなメンバメソッド(__thiscall)を呼び出すには、ラッパをかぶせる→staticでないクラスメンバ関数を_beginthreadで実行させる方法。 - かせいさんとこ
CreateThread
- C++では無くCの関数。
- そのまま使うとメモリリークを起こすので、マルチスレッドなC++では使ってはいけない
- 古いC++のメソッドは、グローバル変数を使ってたり何なりでマルチスレッドに弱いのが多い
- メモリの解放の処理をラップした、beginthreadと、_beginthreadexを使うべし
- MFCの場合は、AfxBeginThreadを使うべきらしい
- 今回はMFCはやんないのでパス
- 参照:CreateThreadと_beginthreadex - blog
_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なメソッド
__stdcall
- staticだが、Windows APIの呼び出し規約に基づいたメソッド。
- 具体的には宣言時に関数名の前にWINAPIをつける。
int WINAPI func( void );
- __cdeclより早いらしい。
詳しくはこちらを参照→二流プログラマの三流な日常: 関数呼び出しの内部を理解する(2)
わかんなかったこと
- _beginthreadの存在理由がいまいち分からず。
- 勝手にハンドルを閉じてくれるのは便利ともいえるけど…。
- スレッド作りっぱなしで、その後、ハンドルを使って色々する気が無いなら、_beginthreadでも良いってこと?
その他
- MSDNデッドリンク多すぎ
参考リンク
トラックバック - http://d.hatena.ne.jp/kasei_san/20080403/p1
リンク元
- 226 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4ADBR_jaJP269JP269&q=__stdcall+マルチスレッド
- 138 http://www.google.co.jp/url?sa=t&rct=j&q=_beginthread&source=web&cd=4&ved=0CEIQFjAD&url=http://d.hatena.ne.jp/kasei_san/20080403/p1&ei=UOWfTqroMYfPmAXzw_nRBA&usg=AFQjCNGpbLZ3VWh_vZsLABYhJvV24_3b8A
- 113 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=2vx&q=_beginthreadex+メンバ関数&btnG=検索&lr=lang_ja
- 68 http://www.google.com/search?hl=ja&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=C+++CreateThread関数&num=50
- 56 http://www.google.co.jp/search?q=_beginthread&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
- 50 http://www.google.co.jp/search?hl=ja&q=スレッド識別子+_beginthreadex&lr=
- 44 http://www.google.co.jp/search?hl=ja&lr=lang_ja&client=firefox-a&rls=org.mozilla:ja:official&hs=my7&q=スレッド+CreateThread&revid=461466282&sa=X&oi=revisions_inline&resnum=1&ct=broad-revision&cd=9
- 44 http://www.google.co.jp/search?sourceid=navclient&aq=t&hl=ja&ie=UTF-8&rlz=1T4ADBR_jaJP222JP229&q=_beginThread
- 39 http://www.google.co.jp/search?hl=ja&q=CreateThread+メモリ解放&lr=&aq=f&oq=
- 38 http://www.google.co.jp/



