Hatena::ブログ(Diary)

かせいさんとこ

2008-04-03

スレッドを調べまわって分かったことをメモ


こうですか?分かりません!><


WIN32のみのお話です。

スレッドって結構実装依存なのね…。


先にまとめ


CreateThread

  • C++では無くCの関数。
  • そのまま使うとメモリリークを起こすので、マルチスレッドなC++では使ってはいけない
    • 古いC++のメソッドは、グローバル変数を使ってたり何なりでマルチスレッドに弱いのが多い
  • メモリの解放の処理をラップした、beginthreadと、_beginthreadexを使うべし
  • MFCの場合は、AfxBeginThreadを使うべきらしい

_beginthreadと、_beginthreadex


そもそもの違いは?

 _beginthread_beginthreadex
呼出規約__cdecl or __clrcall__stdcall or __clrcall
Handleのクローズ終わったら勝手に閉じるCloseHandleで明示的に閉じる必要あり
エラー時の戻り値-10
停止した状態でスレッドを生成×
スレッド識別子×
プロセスへの継承×

どっちが良いの?

オフィシャルとしては、_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デッドリンク多すぎ

参考リンク

dfdf 2011/08/17 23:25 CreateThreadはCの関数ではなく、WIN32API、ウィンドウズの関数です。他にも怪しい記述がただあるのでもう少し調べなおしては?

FILAFILA 2011/12/21 15:25 最近マルチスレッドについて独学している身としては大変ありがたいメモでした
やはりex推奨なんでしょうか・・・
だとするとプログラム組み直さないと・・・

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/kasei_san/20080403/p1