C++ 随机种子、全局对象和 SDL_Threads

Posted

技术标签:

【中文标题】C++ 随机种子、全局对象和 SDL_Threads【英文标题】:C++ Random Seed, Global Objects, and SDL_Threads 【发布时间】:2009-04-16 04:25:38 【问题描述】:

在我的程序中,我有一个全局 cpp 文件对象,它接受一个整数作为参数。

//In global header
extern Object example;

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

我想为对象的参数生成一个随机数,但是种子没有到达全局变量,因为种子是在另一个 cpp 文件中创建的,稍后在 main 中调用。

我的主要问题是随机种子没有达到 global.cpp 中对象的参数,但我也出于特定原因放在那里,这涉及线程。

我的主要问题是: 随机种子可以到达全局变量吗?如果是,请告诉我怎么做

(如果是,则下一个问题无关紧要)

但如果不可能,这个问题与线程和创建对象的位置有关。对象类在run线程中调用一个函数,在另一个线程中调用不同的函数,如下:

//线程A

int thread(void *data)

   example.showimage();

   return 0;


//ThreadB
int thread(void *data(

   example.moveimage();

   return 0;

我想要两个线程之间的这种功能,但是有没有办法在不创建全局对象的情况下实现这一点?

【问题讨论】:

【参考方案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 为您初始化数据。

【讨论】:

【参考方案2】:

听起来您正在使用一种依赖于静态(全局)初始化顺序的方法。您不能跨编译单元(即在不同的文件中)依赖该顺序。同一编译单元中的静态变量按照声明的顺序进行初始化。

对于解决方案,您可以考虑:

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

【讨论】:

【参考方案3】:

您面对的是static initialization problem。最简单的方法是实现一个 Singleton,以便您可以控制初始化过程。当您使用多线程代码时,Singleton 必须是线程安全的(考虑double check locking)模式才能创建,并且可能是互斥锁和避免竞争条件的条件。检查您的线程库文档以获取有关此部分的文档。一般的伪代码是:

// 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),但想法是您有一个单点,两个线程等待另一个线程完成它们的任务,因此没有线程条件。

【讨论】:

以上是关于C++ 随机种子、全局对象和 SDL_Threads的主要内容,如果未能解决你的问题,请参考以下文章

C++ Primer 5th笔记(chap 17 标准库特殊设施)随机数发生器种子( seed)

c++数值61,韦伯分布,随机种子,

c++随机数生成

C++产生随机数

C++ 生成随机数

C++ 实现随机数生成(WindowsLinux)