Увеличить потоки, работающие последовательно, а не параллельно - PullRequest
2 голосов
/ 03 марта 2011

Я - новичок в многопоточности в C ++ и решил начать с Boost Libraries.Кроме того, я использую компилятор Intel C ++ (из Parallel Studio 2011) с VS2010 для Vista.

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

Как я понимаю, всякий раз, когда я запускаю дочерний поток,звезды работают "в фоновом режиме", а родительский поток продолжает выполнять следующую инструкцию, верно?Итак, я подумал о создании и запуске всех необходимых мне дочерних потоков (в цикле for), а затем дождался их завершения (вызову join() каждого потока в другом цикле for), прежде чем продолжить.

Проблема, с которой я сталкиваюсь, заключается в том, что первый цикл не будет переходить к следующей итерации, пока только что созданный поток не завершит работу.Затем второй цикл уже прошел, поскольку все потоки уже соединены к моменту запуска цикла.

Вот (то, что я считаю) соответствующие фрагменты кода.Скажите, есть ли что-нибудь еще, что вам нужно знать.

class Poblacion {
    // Constructors, destructor and other members
    // ...
    list<Individuo> _individuos;
    void generaInicial() { // This method sets up the initial population.
        int i;
        // First loop
        for(i = 0; i < _tamano_total; i++) {
            Individuo nuevo(true);
            nuevo.Start(); // Create and launch new thread
            _individuos.push_back(nuevo);
        }

        // Second loop
        list<Individuo>::iterator it;
        for(it = _individuos.begin(); it != _individuos.end(); it++) {
            it->Join();
        }

        _individuos.sort();
    }
};

И, объект с резьбой Индивидуальный :

class Individuo {
    private:
        // Other private members
        // ...
        boost::thread _hilo;

    public:
        // Other public members
        // ...
        void Start() {
            _hilo = boost::thread(&Individuo::Run, this);
        }
        void Run() {
            // These methods operate with/on each instance's own attributes,
            // so they *can't* be static
            generaHoc();
            calculaAptitud();
            borraArchivos();
        }
        void Join() {
            if(_hilo.joinable()) _hilo.join();
        }
};

Спасибо!:D

1 Ответ

7 голосов
/ 03 марта 2011

Если это ваш реальный код, значит у вас проблема.

    for(i = 0; i < _tamano_total; i++) {
        Individuo nuevo(true);
        nuevo.Start(); // Create and launch new thread
        _individuos.push_back(nuevo);
    }

    void Start() {
        _hilo = boost::thread(&Individuo::Run, this);
    }

Этот код создает новый объект Individuo в стеке, а затем запускает поток, который проходит, передавая указатель thisэтот объект стека в новый поток.Затем копирует этот объект в list, а быстро уничтожает объект стека, оставляя в новом потоке висячий указатель .Это дает вам неопределенное поведение.

Поскольку list никогда не перемещает объект в памяти после его вставки, вы можете запустить поток после вставки в список:

    for(i = 0; i < _tamano_total; i++) {
        _individuos.push_back(Individuo(true)); // add new entry to list
        _individuos.back().Start(); // start a thread for that entry
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...