In my program, I have an object the global cpp file, that takes an integer as an argument.
在我的程序中,我有一个对象是全局cpp文件,它以整数作为参数。
//In global header
extern Object example;
//In global cpp file
Object example( (rand() % 6) );
I want a random number to be generated to the object's argument, but the seed does not reach the global variable, as the seed created in another cpp file, which is called later in the main.
我想要为对象的参数生成一个随机数,但种子不会到达全局变量,因为在另一个cpp文件中创建了种子,后者在main中调用。
My main problem is the random seed does not reach argument of the object in global.cpp, but I also put there for a specific reason, which involves threads.
我的主要问题是随机种子没有达到global.cpp中对象的参数,但我也把它放在那里有一个特定的原因,它涉及线程。
My main question is: Can a random seed reach a global variable? if yes, please tell me how
我的主要问题是:随机种子能否达到全局变量?如果有,请告诉我如何
(ALSO if yes, the next question is irrelevant)
(如果是,则下一个问题无关紧要)
But if it's not possible, this question regards to threads and the where to create the object. The object class calls a function in run thread, and calls a different function on another thread, such as the following:
但如果不可能,这个问题就是线程以及创建对象的位置。对象类在运行线程中调用一个函数,并在另一个线程上调用另一个函数,如下所示:
//Thread A
int thread(void *data)
{
example.showimage();
return 0;
}
//ThreadB
int thread(void *data(
{
example.moveimage();
return 0;
}
I want this kind of functionality between the 2 threads, but is there a way to achieve this without creating the object in globals?
我想在2个线程之间使用这种功能,但是有没有办法在不创建全局变量对象的情况下实现这一点?
3 个解决方案
#1
The best way to do this would be to use the singleton pattern (note that this example is NOT threadsafe):
执行此操作的最佳方法是使用单例模式(请注意,此示例不是线程安全的):
//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());
To implement thread safety, either use a double-lock or some other locking mechanism. Another option would be to look at Boost.call_once to initialize the data for you.
要实现线程安全性,请使用双锁或其他锁定机制。另一种选择是查看Boost.call_once来为您初始化数据。
#2
It sounds like you're using an approach that relys on order of initialization of statics (globals). You cannot depend on that order across compilation units (i.e. in different files). Statics in the same compilation unit are initialized in the order they are declared.
听起来你正在使用一种依赖于静态初始化顺序(全局变量)的方法。您不能在编译单元之间(即在不同的文件中)依赖该顺序。同一编译单元中的静态按其声明的顺序初始化。
For solutions, you might consider this:
对于解决方案,您可以考虑这样:
How do I prevent the "static initialization order fiasco"?
如何防止“静态初始化命令惨败”?
#3
You are facing a static initialization problem. The easiest way out is implemeting a Singleton so that you can control the initialization process. As you are using multithreaded code, the Singleton will have to be thread-safe (consider the double check locking) pattern for creation, and probably a mutex and a condition to avoid race conditions. Check your threading library documentation for documentation on this part. The general pseudo code would be:
您正面临静态初始化问题。最简单的方法是实现Singleton,以便您可以控制初始化过程。当您使用多线程代码时,Singleton必须是线程安全的(考虑双重检查锁定)模式才能创建,并且可能是互斥体和避免竞争条件的条件。有关此部分的文档,请查看您的线程库文档。一般的伪代码是:
// 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();
}
Your threading library probably has better constructs (RAII for mutex acquisition and release()) but the idea is that you have a single point where the two threads wait for the other to complete their tasks so that there is no thread condition.
你的线程库可能有更好的结构(用于互斥锁获取和释放()的RAII),但想法是你有一个点,两个线程等待另一个完成他们的任务,这样就没有线程条件。
#1
The best way to do this would be to use the singleton pattern (note that this example is NOT threadsafe):
执行此操作的最佳方法是使用单例模式(请注意,此示例不是线程安全的):
//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());
To implement thread safety, either use a double-lock or some other locking mechanism. Another option would be to look at Boost.call_once to initialize the data for you.
要实现线程安全性,请使用双锁或其他锁定机制。另一种选择是查看Boost.call_once来为您初始化数据。
#2
It sounds like you're using an approach that relys on order of initialization of statics (globals). You cannot depend on that order across compilation units (i.e. in different files). Statics in the same compilation unit are initialized in the order they are declared.
听起来你正在使用一种依赖于静态初始化顺序(全局变量)的方法。您不能在编译单元之间(即在不同的文件中)依赖该顺序。同一编译单元中的静态按其声明的顺序初始化。
For solutions, you might consider this:
对于解决方案,您可以考虑这样:
How do I prevent the "static initialization order fiasco"?
如何防止“静态初始化命令惨败”?
#3
You are facing a static initialization problem. The easiest way out is implemeting a Singleton so that you can control the initialization process. As you are using multithreaded code, the Singleton will have to be thread-safe (consider the double check locking) pattern for creation, and probably a mutex and a condition to avoid race conditions. Check your threading library documentation for documentation on this part. The general pseudo code would be:
您正面临静态初始化问题。最简单的方法是实现Singleton,以便您可以控制初始化过程。当您使用多线程代码时,Singleton必须是线程安全的(考虑双重检查锁定)模式才能创建,并且可能是互斥体和避免竞争条件的条件。有关此部分的文档,请查看您的线程库文档。一般的伪代码是:
// 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();
}
Your threading library probably has better constructs (RAII for mutex acquisition and release()) but the idea is that you have a single point where the two threads wait for the other to complete their tasks so that there is no thread condition.
你的线程库可能有更好的结构(用于互斥锁获取和释放()的RAII),但想法是你有一个点,两个线程等待另一个完成他们的任务,这样就没有线程条件。