提升线程串行运行,而不是并行运行

ahp*_*ete 2 c++ parallel-processing multithreading boost-thread

我是C++中多线程的完全新手,并决定从Boost Libraries开始.另外,我在Vista上使用英特尔的C++编译器(来自Parallel Studio 2011)和VS2010.

我正在编写一个遗传算法,并希望利用多线程的好处:我想为人口中的每个人(对象)创建一个线程,以便他们并行计算他们的适应度(重度操作),减少总执行时间.

据我所知,每当我启动一个子线程时,它就会"在后台"工作,而父线程继续执行下一条指令,对吧?所以,我想到创建并启动我需要的所有子线程(在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();
    }
};
Run Code Online (Sandbox Code Playgroud)

并且,线程对象个人:

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();
        }
};
Run Code Online (Sandbox Code Playgroud)

谢谢! :D

Ant*_*ams 7

如果这是你真正的代码,那你就有问题了.

    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);
    }
Run Code Online (Sandbox Code Playgroud)

此代码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
    }
Run Code Online (Sandbox Code Playgroud)