2009-04-16 10 views
1

私のプログラムでは、グローバルcppファイルを引数として整数をとるオブジェクトがあります。C++ランダムシード、グローバルオブジェクト、およびSDL_Threads

//In global header 
extern Object example; 

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

私は、オブジェクトの引数に生成される乱数をしたいが、種子は、メインの後半で呼ばれている別のcppファイルで作成された種子、として、グローバル変数には到達しません。

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

私の主な質問は次のとおりです。 ランダムシードはグローバル変数に到達できますか?そうならば、どのよう

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

を教えてください。しかし、それが不可能な場合は、この質問は、スレッドとオブジェクトを作成するところまで考えています。 、

//は

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

    return 0; 
} 

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

    return 0; 
} 

私は2つのスレッド間でこの種の機能が欲しいスレッド:オブジェクトクラスは、次のような、実行スレッド内の関数を呼び出し、別のスレッドで別の関数を呼び出しますグローバルにオブジェクトを作成せずにこれを達成する方法はありますか?

答えて

0

静的(グローバル)の初期化の順序に依存しているようです。コンパイル単位(つまり、異なるファイル)でその順序に依存することはできません。同じコンパイルユニット内の統計は、宣言された順に初期化されます。

ソリューションについて、あなたはこれを検討するかもしれない:

How do I prevent the "static initialization order fiasco"?

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()); 

スレッドの安全性を実装するには、ダブルロックまたはその他のロック機構を使用します。 別のオプションは、Boost.call_onceを見て、データを初期化することです。

0

static initialization problemに直面しています。一番簡単な方法は、初期化プロセスを制御できるようにSingletonを実装することです。マルチスレッドコードを使用している場合、シングルトンはスレッドセーフ(double check lockingと考える)パターンを作成する必要があります。また、競合状態を回避するためのmutexと条件が必要です。このパートのドキュメントについては、スレッドライブラリのドキュメントを参照してください。一般的な擬似コードは次のようになります。

// 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(); 
} 

あなたのスレッドライブラリは、おそらくより良い構造(ミューテックスの獲得と解放のためのRAIIを())があるが、アイデアは、あなたが2つのスレッドがする他のを待つの単一のポイントを持っているということですスレッド条件が存在しないようにタスクを完了します。