2011-03-03 20 views
2

我是C++多线程的完全新手,并决定从Boost库开始。另外,我在Vista上使用了英特尔的C++编译器(来自Parallel Studio 2011)。我想编写一个遗传算法,并希望利用多线程的好处:我想为群体中的每个个体(对象)创建一个线程,以便他们计算它们的适应度(繁重的操作),以减少总执行时间。提升线程串行运行,不并行

据我所知,无论何时我启动一个子线程,它会在后台运行,并且父线程继续执行下一条指令,对不对?所以,我想创建并启动我需要的所有子线程(在for循环中),然后等待它们完成(在另一个for循环中调用每个线程的join()),然后继续。

我面临的问题是,第一个循环将不会继续下一个迭代,直到新创建的线程完成工作。然后,第二个循环和消失一样好,因为所有的线程在循环被击中的时候已经加入了。

这里是(我认为是)相关的代码片段。告诉我是否还有其他需要知道的事情。

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(); 
    } 
}; 

而且,螺纹对象Individuo

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

有趣的是做这种事与如Boost.Threads,但OpenMP的将使它更容易 – CharlesB 2011-03-03 10:41:30

+0

@CharlesB我认为,对于这种特殊情况下,问题已解决,但我会考虑OpenMP。感谢您的建议。 – ahpoblete 2011-03-03 19:31:04

回答

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); 
    } 

此代码创建的堆栈上的新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 
    } 
+0

是的!这正是问题所在。我确定它与'list.push_back()'复制对象有关(因为我必须重载copy ctor,但不能真正解决问题 - 我尝试使用指向线程的指针而不是线程,但是它只会产生一些奇怪的引用计数错误)。但我离题了......非常感谢! – ahpoblete 2011-03-03 19:26:48