3

私は現在、Allegroクロスプラットフォームライブラリを使用して、Cでインディーゲームの開発を始めています。プログラムの堅牢性を高めるために、入力、サウンド、ゲームエンジン、グラフィックスなどをそれぞれのスレッドに分離することにしました。マルチスレッドの経験がまったくないので、私の質問は次のとおりです。

メモリ内にデータのセクション(たとえば、データ構造へのポインター)がある場合、1つのスレッドが自由に書き込み、別のスレッドが自由に読み取ることができますか、それとも各スレッドがミューテックスを使用する必要がありますか?メモリをロックしてから読み取りまたは書き込みをしてからロックを解除するには?

特に、ゲームエンジンとビデオレンダラーの相互作用について考えていました。(これは2Dです。)私の計画は、エンジンがユーザー入力を処理し、スピーカーとモニターに供給される適切なオーディオとビデオを吐き出すことでした。画面に描画される次のビットマップへのグローバルポインタがあると思っていました。ゲームエンジンとレンダラーのコードは次のようになります。

ALLEGRO_BITMAP *nextBitmap;
boolean using;

void GameEngine ()
  {

  ALLEGRO_BITMAP *oldBitmap;

  while (ContinueGameEngine())
    {
    ALLEGRO_BITMAP *bitmap = al_create_bitmap (width, height);
    MakeTheBitmap (bitmap);
    while (using) ; //The other thread is using the bitmap. Don't mess with it!
    al_destroy_bitmap (nextBitmap);
    nextBitmap = bitmap;
    }

  }

void Renderer ()
  {

  while (ContinueRenderer())
    {
    ALLEGRO_BITMAP *bitmap = al_clone_bitmap (nextBitmap);
    DrawBitmapOnScreen (bitmap);
    }

  }

これは不安定なようです...への呼び出しで何かが起こるかもしれませんal_clone_bitmapが、私はこのようなものを処理する方法がよくわかりません。ビットマップでミューテックスを使用しますが、ミューテックスはロックとロック解除に時間がかかるようです。これらのスレッド(特にゲームエンジンスレッド)の両方をできるだけ高速に実行したいと思います。条件と呼ばれるものについても読みましたが、条件がどのように適用可能または有用であるかは確かですが、まったくわかりません。誰かが私にミューテックスと条件(できればWindowsではなくPOSIX)に関するチュートリアルを教えてもらえますか?それで私はこれをすべて理解しようと試みることができますか?

4

4 に答える 4

1

必要なツールはアトミック操作と呼ばれ、リーダースレッドが他のスレッドによって書き込まれたデータ全体のみを読み取るようにします。このような操作を使用しない場合、データは部分的にしか読み取られない可能性があるため、読み取った内容がアプリケーションの観点からまったく意味をなさない可能性があります。

新しい標準C11にはこれらの操作がありますが、まだ広く実装されていません。しかし、多くのコンパイラには、これらを実装する拡張機能が必要です。__syncたとえば、gccには、プレフィックスで始まる一連の組み込み関数があります。

于 2012-12-20T08:17:38.030 に答える
1

メモリ内にデータのセクション(たとえば、データ構造へのポインター)がある場合、1つのスレッドが自由に書き込み、別のスレッドが自由に読み取ることができますか?

答えは「状況によって異なります」で、通常は「いいえ」を意味します。

書き込み/読み取りの内容によっては、またプログラムのロジックによっては、同期なしで書き込みと読み取りを行おうとすると、書き込みと読み取りがアトミックであるかどうかが完全にわからない場合、結果がワイルドになったり破損したりする可能性があります。 。

したがって、次の場合を除いて、ミューテックスを使用する必要があります。

  1. 書き込みと読み取りがアトミックであること、および1つのスレッドが読み取りのみであることを絶対に確信しています(理想的にはInterlocked、WinAPIの関数ファミリーなどのアトミック操作に何らかの特定のサポートを使用します)。
  2. ロックしないことによるわずかなパフォーマンスの向上が絶対に必要です。

また、while (using);コンストラクトの信頼性と精度が大幅に向上し、スピンロックを使用した場合(ミューテックスではなくスピンロックが必要であると確信している場合)は、おそらくパフォーマンスが向上することにも注意してください。

于 2012-12-20T07:30:24.760 に答える
0

'google'にはたくさんのマニュアルページがあります。それらを検索します。数分でhttp://www.yolinux.com/tokyoS/LinuxTutorialPosixThreads.htmlが見つかりました。

その上、ほんの少しの例から始めて、難易度を上げていきます。最初にスレッドの作成と終了、スレッドの戻り、スレッドの構文化を行います。posix mutexと条件を続行し、これらすべての用語を理解します。

重要なドキュメントフィードの1つは、Linuxのmanページと情報ページです。

幸運を

于 2012-12-20T07:29:44.197 に答える
0

メモリ内にデータのセクション(たとえば、データ構造へのポインター)がある場合、1つのスレッドが自由に書き込み、別のスレッドが自由に読み取ることができますか、それとも各スレッドがミューテックスを使用する必要がありますか?メモリをロックしてから読み取りまたは書き込みをしてからロックを解除するには?

2つの異なるスレッドが読み取りと書き込みを行っているデータのセクションがメモリにある場合、これはクリティカルセクションと呼ばれ、コンシューマーとプロデューサーの共通の問題です。

この問題について話す多くのリソースがあります:

ただし、2つの異なるスレッドを使用して読み取りと書き込みを行う場合は、ミューテックスの使用または別の形式のロックとロック解除を実装する必要があります。

于 2018-02-11T19:39:00.023 に答える