-1

次の方法で実行される OpenGL プログラムを作成しました。

Main:
- Initialize SDL
- Create thread which has the OpenGL context:
    - Renderloop
        - Set camera (view) matrix with glUniform.
        - glDrawElements() .... etc.
        - Swapbuffers();
- Main SDL loop handling input events and such.
    - Update camera matrix of type glm::mat4. 

これは、opengl を処理するクラスにカメラ オブジェクトを渡す方法です。

Camera *cam = new Camera();
gl.setCam(cam);

どこ

void setCam(Camera *camera) {
    this->camera = camera;
}

opengl コンテキスト スレッドでのレンダリングでは、次のようになります。

glm::mat4 modelView = camera->view * model;
glUniformMatrix4fv(shader->bindUniform("modelView"), 1, GL_FALSE, glm::value_ptr(modelView));

SDL などを処理するメイン プログラムで、ビュー マトリックスを再計算します。これは、ミューテックスロックを使用しなくても正常に機能します。これは正しいです?

一方、「アップロード キュー」によってシーンにオブジェクトを追加します。この場合、アイテムを追加するときにアップロード キュー ベクター (ベクター クラス タイプ) をミューテックス ロックする必要があります。そうしないと、プログラムがクラッシュします。

要約すると、別のスレッドで行列を再計算し、ミューテックス ロックなしで opengl スレッドで使用します。なぜこれが機能するのですか?

編集: 私の質問はここで尋ねられたものと似ていると思います:

1)あるスレッドで変数をロックする必要があるのは、その変数の値が他のスレッドで必要な場合のみです。、私の場合のみ、変更されるマトリックスが1つだけでさらに単純です。

2) 1 つのスレッドだけが共有変数に書き込む場合、ロックは必要ですか?

4

2 に答える 2

2

なぜこれが機能するのですか?

誰がそれだと言いますか?

マルチスレッド コードの経験則は非常に単純です。マルチスレッド コードが確実にスレッド セーフでない場合、デフォルトでは間違っています。

ミューテックスやその他の同期構造により、コードが機能することを証明できます。その実証済みの機能がなければ、サイコロを振るだけです。多分あなたはそのマシンで幸運です。コンピューターを再起動すると、動作しなくなる可能性があります。くしゃみしたら壊れるかも。

何かがたまたま意図したとおりに機能するからといって、それが機能するとは限りません。泥棒が警察に捕まらないのと同じように、あなたがそれを逃れたというだけで、彼らが再びそれを試みても彼らが彼を捕まえないという意味ではありません.

必要に応じて、証明されていないスレッド コードに依存することを選択できます。または、物事を正しく行うことができ、心配する必要はありません。


私が理解しているように、私がどこでやるかと同じように動作します

いいえ、そうはなりません。

最初のケースでは、スタック オブジェクトへのポインターを渡しています。そのスタック オブジェクトは、スコープが終了すると破棄されます。その時点以降、そのポインターを何かに使用しようとすると、問題が発生します。

2 番目のケースでは、新しくヒープに割り当てられたオブジェクトへのポインターを渡しています。あなたがそれを破壊すると、そのオブジェクトは破壊されます。誰かがこのオブジェクトを削除する責任を負う必要があります。おそらく、そのポインターを に渡すとgl.setCamglオブジェクトは適切なタイミングで破棄する責任を負います。

これは標準的な C++ のものです。OpenGL、複数のスレッドなどとは何の関係もありません。これはすべて、所有権の概念に関するものです。スタックが所有していたメモリを、その所有権を主張することを期待していた関数に渡しました。あなたは守れない約束をした。したがって、ブーム。

于 2012-10-11T01:47:31.113 に答える
0

なぜこれが機能するのですか?

わかりません。私のクリスタル オーブが壊れていて、あなたはコードを教えてくれませんでした。OpenGL にはカメラがなく、Camera クラスを使用しているため、いくつかのコピーが回っている可能性があります (メモリ リークの可能性があります)。

于 2012-10-11T00:40:14.110 に答える