Slim Reader Writer ロック

WindowsのWin32APIの話、実験してないので予想で記述。

Vistaから使える

Vistaから使える。

クリティカルセクションに比べて早い

クリティカルセクションはリーダーとかライターの区別がないので、リーダーがたくさん動いていると大変になる場合がある。

ShareモードとExclusiveモードがある

同じロックに対してSharedモードで取得するかExclusiveモードで取得するか選択できる。Shareモードをロックした場合は次のShareモードロックも取得できるはず。Exclusiveはロックが全くない場合だけ取得できるはず。Exclusiveがロックされているときはどっちも取得できない。

再取得できない

クリティカルセクションは取得後に再取得できたがこれはできないらしい。小さなコードブロックで使いデッドロックしないように注意。

使い方

  • InitializeSRWLockで初期化、またはSRWLOCK_INITを直接設定
  • AcquireSRWLockSharedでShareモードロックを取得、ReleaseSRWLockSharedで開放
  • AcquireSRWLockExclusiveでExclusiveモードロックを取得、ReleaseSRWLockExclusiveで開放

 

 

 

VC6でデバッグビルドでは動くのにリリースビルドだと動かない場合

リリースビルドでもデバッグ情報をある程度付け足してビルドすることができるのでその方法。

1、メニューの「ビルド」「構成」からリリースビルドの構成を元に新しい構成を作成する。

2、プロジェクトの設定の、「C/C++」でデバッグ情報を「プログラムデータベースを使用」にする。「リンク」で、「デバッグ情報を生成する」をチェックする。

3、実行してエラーが出てくれれば、行番号などのある程度の情報はわかる。

上の方法でエラーが出てくれないとき。

1、リリースビルドのプロジェクトの設定の「リンク」で「MAPファイル生成」をチェックし、ビルドすると拡張子MAPのファイルができる。このファイルは関数のアドレス情報がわかる。

2、実行してエラーを再現して、エラーの起きたアドレスを調べる。以下の場合ならアドレスは0x401106になる。

err

3、MAPファイルからこのアドレスがどの関数かを調べる。左の数値ではなく右のほうの400000あたりから始まる数値。

4、頑張ればコールスタックも調べられる。

GetLastErrorで取得した番号をFormatMessageで文字列に変換する

MFCのCStringバージョン。
GetLastErrorの値を上書きされないために、変な宣言になってる。

一部はMSのサイトに載ってたもので、詳しくは調べていない。

SetRedrawを使ってちらつきを抑え、処理を速くする

MFCとWin32の話です。

TreeViewやListViewに多くのアイテムを追加したり、アイテムを全部削除する場合、結構時間がかかります。どうもこれは一個足したり消したりする毎に描画処理が走ってる様なので、SetRedrawを使ってこの描画を抑えることにより、処理が高速化し、ちらつきも抑えられます。

サンプルプログラム(ツリービューのアイテムを全部削除)

Win32APIの場合はWM_SETREDRAWを使います。

実際にコードを書く場合は、SetRedraw(FALSE)を呼んだあとはSetRedraw(TRUE)が必ず呼ばれるようにしたほうがいいかもしれません。また、処理が終わったら以下のようにウインドウを再描画したほうがいいかもしれません。