1

私のプログラムには、引数として整数を取るグローバル cpp ファイルというオブジェクトがあります。

//In global header
extern Object example;

//In global cpp file
Object example( (rand() % 6) );

オブジェクトの引数に乱数を発生させたいのですが、後でメインで呼び出される別のcppファイルで作成されたシードとして、シードがグローバル変数に到達しません。

私の主な問題は、ランダムシードがglobal.cppのオブジェクトの引数に到達しないことですが、スレッドを含む特定の理由でそこに置きました。

私の主な質問は次のとおりです。ランダムシードはグローバル変数に到達できますか? はいの場合、方法を教えてください

(また、はいの場合、次の質問は無関係です)

しかし、それが不可能な場合、この質問はスレッドとオブジェクトを作成する場所に関するものです。オブジェクト クラスは、次のように実行スレッドで関数を呼び出し、別のスレッドで別の関数を呼び出します。

//スレッド A

int thread(void *data)
{
   example.showimage();

   return 0;
}

//ThreadB
int thread(void *data(
{
   example.moveimage();

   return 0;
}

2 つのスレッド間でこの種の機能が必要ですが、グローバルでオブジェクトを作成せずにこれを実現する方法はありますか?

4

3 に答える 3

1

これを行う最良の方法は、シングルトンパターンを使用することです(この例はスレッドセーフではないことに注意してください)。

//in a header
class RandomSeed
{
public:
    static RandomSeed& instance()
    {
        static RandomSeed the_instance;
        return the_instance;
    }
    int value() const {return value_;}
private:
    RandomSeed() {/*initialization code*/}
    RandomSeed(const RandomSeed& rs); // disallowed
    RandomSeed& operator=(const RandomSeed& rs); // disallowed
    int value_;
};

// in your file
#include "random_seed.h"
srand(RandomSeed::instance().value());

スレッドセーフを実装するには、ダブルロックまたはその他のロックメカニズムを使用します。もう1つのオプションは、Boost.call_onceを調べてデータを初期化することです。

于 2009-04-16T05:50:36.807 に答える
0

スタティック(グローバル)の初期化の順序に依存するアプローチを使用しているようです。コンパイルユニット間(つまり、異なるファイル内)でその順序に依存することはできません。同じコンパイルユニット内の統計は、宣言された順序で初期化されます。

ソリューションについては、次のことを検討してください。

「静的初期化順序の大失敗」を防ぐにはどうすればよいですか?

于 2009-04-16T05:48:10.230 に答える
0

静的な初期化の問題に直面しています。最も簡単な方法は、初期化プロセスを制御できるようにシングルトンを実装することです。マルチスレッドコードを使用しているため、シングルトンはスレッドセーフ(ダブルチェックロックを検討)パターンで作成する必要があり、競合状態を回避するためにミューテックスと条件を使用する必要があります。この部分のドキュメントについては、スレッドライブラリのドキュメントを確認してください。一般的な擬似コードは次のようになります。

// image_control would be 'example' in your two last snippets
// painter
image image_control::obtain_picture()
{
   mutex.acquire();
   while ( ! image_already_created ) 
      image_creation_condition.wait(); // wait for image creation
   image res = the_image;
   image_already_created = false; // already consumed
   image_consumption_condition.signal(); // wake up producer is waiting
   mutex.release();
   return res;
}
// image creator
void image_control::create_picture( image new_image )
{
   mutex.acquire();
   while ( image_already_created ) 
      image_consumption_condition.wait(); // wait for image to be consumed
   the_image = new_image;
   image_already_created = true;
   image_creation_condition.signal(); // wake up consumer if it is waiting
   mutex.release();
}

スレッドライブラリにはおそらくより優れた構造(ミューテックスの取得とrelease()用のRAII)がありますが、スレッドの状態がないように、2つのスレッドが他方のスレッドがタスクを完了するのを待つ単一のポイントがあるという考え方です。

于 2009-04-16T05:51:40.937 に答える