none
マルチスレッドでのメンバ変数 RRS feed

  • 質問

  • 下記のようなクラスをマルチスレッドで場合、メンバ変数mVecは同期することを考慮しなければならないですか?

    class A {

    std::vector<int> mVec;

    set(int i) {mVec.push_back(i);}

    int get(int i) {return mVec(i);}

    };

    2011年1月31日 5:13

回答

  • 同期の要否はクラス単体では判断できなくて、インスタンスがどのように使用されているか(文脈)によって変わってきますよ。
    同期をするにしてもトランザクションを意識しないといけないので、クラスの内部だけで閉じるのは意味がないこともあります。

    参考:
     STLとMulti Thread
     http://social.msdn.microsoft.com/Forums/ja-JP/vcgeneralja/thread/ea660164-1e39-4e6d-abc8-b711bc3bbb17/
    • 回答としてマーク 山本春海 2011年2月28日 7:32
    2011年1月31日 6:01
  • 質問の意味が不明なので、これでは誰も回答できないでしょう。
     1.classAとスレッドの関係をもう少し詳しく説明し
     2.懸念している状況について解説してから
     3.あれば仮説を述べ
     4.不明な点を質問
    してみてください。
    • 回答としてマーク 山本春海 2011年2月28日 7:32
    2011年1月31日 6:15
  • 一般論で書きます。
    仲澤さんが書かれている通り、前提条件の部分が説明されていないので
    こちらが想像している内容で当たっているかどうかが怪しいので。

    マルチスレッドは複数のスレッドが同時に動作するものですが、同時にと言うのはマクロな目で
    見た時の話で、ミクロな目で見るとある瞬間に動作しているスレッドは一つです。
    で、結局の話、マルチスレッドは各スレッドの処理をコマ切れにして平行してちょっとずつ進めている
    から結果的に同時進んでいるように見えているわけです。
    じゃあ、OSがどの単位で処理をコマ切れにしてスレッドを切り替えているかと言うと
    関数の呼出単位なんていう大きな単位ではなく、もっと細かい単位で切り替えています。
    そう考えるとGetを呼んでいる最終にSetが呼ばれてしまったり、あるスレッドでSetを呼んでいる
    最中に他のスレッドでSetが呼ばれてしまったりと言う事は十分ありえるわけです。

    マルチスレッド時のこういった不都合を解消する為にはあるスレッドが処理中は他のスレッドには
    まって貰うと言う様な処理が必要になります。
    で、何処から何処までの処理の間は割り込まれては困るというような話がtotojoさんが書かれている
    トランザクションを意識するという話です。
    単純にSetが二つ同時に走らない程度で良いなら単純な排他で何とかなると思いますが、
    実際にはもっと大きな処理の単位で排他を掛けるケースがあるので考慮が必要です。


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 回答としてマーク 山本春海 2011年2月28日 7:32
    2011年2月4日 1:57
  •  それとも、こういう話?


    Jitta@わんくま同盟
    • 回答としてマーク 山本春海 2011年2月28日 7:32
    2011年2月16日 12:12

すべての返信

  • 同期の要否はクラス単体では判断できなくて、インスタンスがどのように使用されているか(文脈)によって変わってきますよ。
    同期をするにしてもトランザクションを意識しないといけないので、クラスの内部だけで閉じるのは意味がないこともあります。

    参考:
     STLとMulti Thread
     http://social.msdn.microsoft.com/Forums/ja-JP/vcgeneralja/thread/ea660164-1e39-4e6d-abc8-b711bc3bbb17/
    • 回答としてマーク 山本春海 2011年2月28日 7:32
    2011年1月31日 6:01
  • 質問の意味が不明なので、これでは誰も回答できないでしょう。
     1.classAとスレッドの関係をもう少し詳しく説明し
     2.懸念している状況について解説してから
     3.あれば仮説を述べ
     4.不明な点を質問
    してみてください。
    • 回答としてマーク 山本春海 2011年2月28日 7:32
    2011年1月31日 6:15
  • 一般論で書きます。
    仲澤さんが書かれている通り、前提条件の部分が説明されていないので
    こちらが想像している内容で当たっているかどうかが怪しいので。

    マルチスレッドは複数のスレッドが同時に動作するものですが、同時にと言うのはマクロな目で
    見た時の話で、ミクロな目で見るとある瞬間に動作しているスレッドは一つです。
    で、結局の話、マルチスレッドは各スレッドの処理をコマ切れにして平行してちょっとずつ進めている
    から結果的に同時進んでいるように見えているわけです。
    じゃあ、OSがどの単位で処理をコマ切れにしてスレッドを切り替えているかと言うと
    関数の呼出単位なんていう大きな単位ではなく、もっと細かい単位で切り替えています。
    そう考えるとGetを呼んでいる最終にSetが呼ばれてしまったり、あるスレッドでSetを呼んでいる
    最中に他のスレッドでSetが呼ばれてしまったりと言う事は十分ありえるわけです。

    マルチスレッド時のこういった不都合を解消する為にはあるスレッドが処理中は他のスレッドには
    まって貰うと言う様な処理が必要になります。
    で、何処から何処までの処理の間は割り込まれては困るというような話がtotojoさんが書かれている
    トランザクションを意識するという話です。
    単純にSetが二つ同時に走らない程度で良いなら単純な排他で何とかなると思いますが、
    実際にはもっと大きな処理の単位で排他を掛けるケースがあるので考慮が必要です。


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 回答としてマーク 山本春海 2011年2月28日 7:32
    2011年2月4日 1:57
  •  それとも、こういう話?


    Jitta@わんくま同盟
    • 回答としてマーク 山本春海 2011年2月28日 7:32
    2011年2月16日 12:12
  • こんにちは、がーぷ さん。

    MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。
    しばらく時間が経ちましたが、みなさんからのアドバイスは確認いただけましたでしょうか。

    みなさんからいただいた投稿は参考になる情報かと思われましたので、勝手ながら私のほうで回答としてマークさせていただきました。
    レスポンスくださった皆さん、ありがとうございます。

    もし、意図している内容はちょっと違った。。。などありましたら、詳細を投稿いただいてご質問を続けてくださいね。

    今後とも、MSDN フォーラムをよろしくお願いいたします。
                                                                          
    日本マイクロソフト株式会社 フォーラム オペレーター 山本 春海

     

    2011年2月28日 7:32