1

私のプログラムは、 main( )。main() は「world」自体の更新を処理し、関数 updateDisplay() は「world」の内容をモニターに表示します。updateDisplay() は別の C++11 スレッド (main() で開始される) によって実行され、渡された参照を介して「世界」にアクセスします。

私の問題は、以下の updateDisplay() からの (簡略化された) コードの抜粋で、ベクトル world.m_grid[i][j].m_rabbit が " if (!world.m_grid[i][j].m_rabbit.empty())" updateDisplay() をチェックインしますが、その後 m_rabbit[0] ベクトル メンバーにアクセスする前に、「ベクトル添え字が範囲外」になります。エラー。

for (int i = 0; i < rows; ++i)
{
    for (int j = 0; j < columns; ++j)
    {

        if (!world.m_grid[i][j].m_rabbit.empty())
        {
            s_rabbit_64.setScale(absTileScale * world.m_grid[i][j].m_rabbit[0].m_size, absTileScale * world.m_grid[i][j].m_rabbit[0].m_size);
            s_rabbit_64.setPosition(x * k + (12 * absTileScale), y * (i - winFocus.y) + (12 * absTileScale));
            window.draw(s_rabbit_64);
        }
    }
}

私の質問は、world.m_grid[i][j].m_rabbit ベクトルをロックダウンして、updateDisplay() スレッドがアクセスしている間、main() が変更できないようにするにはどうすればよいですか? これは std::mutex を使用することで達成できると思いますが、これを自分のプログラムに適用するのに十分な理解を与えるガイドを見つけることができませんでした。これが理解できるほど明確であることを願っています (プログラムはこの抜粋よりもはるかに大きく、大規模なテキスト ダンプを行いたくありませんでした)。必要な点について説明を求めてください。

ご清聴ありがとうございました。

[編集] つづり

4

2 に答える 2

3

マルチスレッドのワイルドで毛むくじゃらの世界へようこそ。座ってください; あなたは長い間ここにいるでしょう。のように、あなたのプログラミングのキャリアの残りの部分は長いです。それは恐ろしく、裏切りと微妙なバグでいっぱいです。また、正しく実行できれば、非常にうまくいきます:-)

実際、この場合、特定のバグを特定するのにかなり良い仕事をしました。必要なのは、スレッド間で共有される状態のすべてのアクセスと変更を保護するミューテックスを持つことです。あなたの場合:ベクトルをクリアする前にメインスレッドでミューテックスをロックし、完了後にミューテックスのロックを解除します。同様に、アクセスする前に処理スレッドでミューテックスをロックし、完了したらロックを解除します。この特定のケースでは、そこに行った double-for ループ全体をロックしてしまう可能性があります。

この答えは、ミューテックスが何をしているかのかなり良い説明です。


はい、物事を行うためのより速くてエレガントな方法がありますが、今のところは正しいことに固執しましょう。

于 2013-01-29T05:19:58.297 に答える
1

コードのクリティカル セクションを特定する必要があります。上記の投稿から、 world.m_grid[i][j].m_rabbit を変更する操作はクリティカル セクションのようです。

次に、一度に 1 つのスレッドのみが特定のクリティカル セクションに入ることができるような、ある種の同期手法が必要です (たとえば、ミューテックス)。

Web を検索して良い読み物を探す必要があります。または、優れたプログラミングの本を見つけて、並行処理の章に時間を割く必要があります。

于 2013-01-29T05:44:01.970 に答える