C ++ Случайное семя, глобальные объекты и SDL_Threads - PullRequest
1 голос
/ 16 апреля 2009

В моей программе у меня есть объект глобальный файл 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;
}

Мне нужна такая функциональность между двумя потоками, но есть ли способ достичь этого, не создавая объект в глобальных переменных?

Ответы [ 3 ]

1 голос
/ 16 апреля 2009

Лучший способ сделать это - использовать шаблон синглтона (обратите внимание, что этот пример НЕ является потокобезопасным):

//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 голосов
/ 16 апреля 2009

Вы столкнулись с проблемой статической инициализации . Самый простой выход - реализовать 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();
}

Ваша потоковая библиотека, вероятно, имеет лучшие конструкции (RAII для захвата и освобождения мьютекса ()), но идея в том, что у вас есть единственная точка, в которой два потока ждут, пока другой завершит выполнение своих задач, чтобы не было условия потока.

0 голосов
/ 16 апреля 2009

Похоже, вы используете подход, основанный на порядке инициализации статики (глобальные переменные). Вы не можете зависеть от этого порядка в разных единицах компиляции (то есть в разных файлах). Статики в том же модуле компиляции инициализируются в порядке их объявления.

Для решений вы могли бы рассмотреть это:

Как предотвратить «фиаско статического порядка инициализации»?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...