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的主要内容,如果未能解决你的问题,请参考以下文章