dポイントプレゼントキャンペーン実施中!

スレッドAで通常読み書きを行っている、非常に関係性の深い変数が複数あり、それらは書き換えられる場合、同一関数内などでほぼ同時に書き換えられるとき

スレッドBからは全く書き換えは行わず、読み取り専用のアクセスのみをするとし

一つのCRITICAL_SECTIONでそれらを全て保護するとすれば

Aで書き換えを行う(或いはそのための計算)部分は全てを囲み
(つまり全ての変数を囲う)

また、それらの変数がスレッドBから参照される部分は囲む

これでスレッドセーフになり、それ以外は囲う必要はない。
(例えばスレッドAから単に読み取り専用のアクセスをされる場合などは普通にシングルスレッドと同様の考え方で良い)


という考えで問題ないでしょうか?

また、スレッドAからしか書き換えを行わなければ
いくつ読み取り専用の別スレッドが出来たとしても

同様に

Aで書き換えを行う部分と
スレッドCやスレッドD・・・
から参照される部分さえ囲んでおけばスレッドセーフになる

という考えで問題ないでしょうか?

A 回答 (1件)

そのデータ群に関してはそれでスレッドセーフになると思います。

わかりやすくしたければ、共有するデータ群を別クラスにして、そのクラスに同期オブジェクトを埋め込んでやれば記述はすっきりするかもしれません。
    • good
    • 0
この回答へのお礼

どうもどうも、ありがとうございます♪

これが確認できればすっきりです。今後も役に立つことは間違いありません。


>共有するデータ群を別クラスにして、そのクラスに同期オブジェクトを埋め込んでやれば記述はすっきりするかもしれません。


なるほど…!

確かに、コスト(最小限の呼び出し)と利便性(関数名などで分かりやすく、かつ見た目上短く表記できる)の両方をとろうとするなら
そのためだけにクラスを作ってしまうという手も、状況次第で十分考えられそうですね。

私が質問時に関係性の深い変数といったのは、具体的にはポインタのポインタ(動的確保をする)とその確保時の要素数を示す整数のことでしたが


クラスのコンストラクタとデストラクタを利用して、関数の出口が複数ある場合にクリティカルセクションの解除忘れを防ぐ。という別クラスの利用アイデアは、読んだことがあったのですが


それについては、今回は頻繁に呼び出される可能性も否定できなかったので、コンストラクタとデストラクタのオーバーヘッドを考えて使っていませんでした。

依然、マルチスレッド用描画(GDI)関連に関しては専用クラスを作ったことがあったのですが、今回保護する変数が2つのみだったので、そこで「別クラスを作る」という方向に対しては思考停止していました。




しかし、そのためのクラスといっても、そういう組み方と限る必要はなく、Dodonpa2さんがおっしゃるように、このことのために独自に作るとすれば、コンストラクタやデストラクタを呼ぶ必要ないように書き、インライン展開で関数呼び出しのオーバーヘッドの可能性を完全に撤廃などできれば
コスト面で劣らない書き方も可能(ただし、その場合は分かりやすくするという意味あいのみになるかもしれませんが)


あるいは、今回の場合にも流用できる可能性として
「何かを動的配列確保するためのポインタ」と「要素数を示す整数」と「クリティカルセクション」をもつようなtemplateのクラスを、インライン展開をしっかり意識して作っておけば、同じようなことには十分使いまわせるかもしれません。


その辺、どういう手を使うかは、やはりプログラミングの醍醐味ですね。

お礼日時:2011/04/04 04:54

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!