2011-03-03 53 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