2016-08-22 5 views
-2

異なる関数と同じ引数オブジェクトを持つ2つのスレッドがそれらのオブジェクトに対して異なる値を与えるという問題があります。 clearifyする同じ引数オブジェクトを持つスレッドは異なる値を返します

、次のコードを守ってください:

class Player(){ 
    // Definition of Player here 
    // with get- and set functions 
    // for a certain value. 
} 

class Game(){ 
    static void Draw(Player p){ 
     while(1){ 
      gotoxy(p.getValue(), 15); 
      cout << p.name(); 
     } 
    } 

    static void Move(Player p){ 
     int x = p.getValue(); 
     while(1){ 
      if(_kbhit()){ 
       p.setValue(++x); 
      } 
     } 
    } 

    void startGame(){ 
     Player pl1(5); 

     thread thd1(Move, pl1); 
     thread thd2(Draw, pl1); 
     thd1.join(); 
     thd2.join(); 
    } 

} 

関数内でその値を取得するときの「x」「描画」、すべてのキーストロークのための関数「移動」が変化している値がまだありますが'pl1'の初期値(5)です。

「移動」が指定したのと同じ値を得るには、どのように「描画」を得ることができますか? 私は何か助けと指導を感謝します。

ありがとうございます!

+1

スレッドの使い方を学ぶだけで済みます。これには迅速かつ簡単な答えが1つありません。アドレス空間を共有する実行フローの概念全体を理解する必要があります。あなたは、スレッド間で情報を共有/交換するために、ある種の方法が必要です。それはすべて確実にそれ自体では起こりません。 –

答えて

1

あなたは

static void Move(Player pl) 

ではなく、参照/ポインタによって値によってプレイヤーを渡しているので、両方の機能がコピー元の変数の、彼らの、独自のローカルを持っています。

static void Move(Player& pl) 

は、変数を参照して、両方の関数に元の変数へのアクセスを与えます。

また、getValuesetValueが何らかの形式のロックを実装していない限り、このコードはスレッドセーフではありません。

+1

参照渡しであっても、最適化コンパイラは 'getValue'への呼び出しを最適化でき、値の変更は読み取りスレッドでは見えなくなります。したがって、スレッドの同期は絶対に重要です! –

1

問題は、pl1を値渡しして、参照渡しにしたい場合です。 pl1を各関数に渡しているように見えますが、実際に何が起こっているかは、MoveおよびDrawスレッドがそれぞれ新しいPlayerオブジェクトを構築していることです。参照渡しの場合、両方のスレッドは、独自のコピーを作成するのではなく、同じオブジェクトを参照します。関数のシグネチャを次のように変更してみてください。

static void Move(Player &p); 
static void Draw(Player &p); 

また、関数にいくつかの終了条件を設定することを検討してください。 while(1)は決して終了しないので、join()関数は永遠に待機します。希望が助けてくれる!

関連する問題