2011-03-03 4 views
2

전 C++로 멀티 스레딩하는 완전한 초보자이고 Boost Libraries로 시작하기로 결정했습니다. 또한 필자는 Vista의 VS2010과 함께 Intel의 C++ 컴파일러 (Parallel Studio 2011)를 사용하고 있습니다.병렬로 실행되지 않는 연속적으로 실행되는 부스트 스레드

저는 유전자 알고리즘을 코딩하고 있으며 멀티 스레딩의 이점을 이용하려고합니다. 개체의 체력 (체중)을 계산할 수 있도록 각 개체 (개체)에 대한 스레드를 만들고 싶습니다.)를 병렬로 실행하여 총 실행 시간을 줄입니다.

내가 이해하는 것처럼, 자식 스레드를 시작할 때마다 "백그라운드에서"작동하며 부모 스레드는 다음 명령어를 계속 실행합니다. 맞습니까? 그래서, 나는 (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(); 
    } 
}; 

그리고, 스레드 객체 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

+0

@CharlesB 저는이 특별한 경우에 문제가 해결되었다고 생각하지만 OpenMP를 살펴 보겠습니다. 제안 해 주셔서 감사합니다. – ahpoblete

답변

7

실제 코드라면 문제가있는 것입니다.

이 코드는 스택에 새로운 Individuo 객체를 생성
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); 
    } 

는, 새로운 스레드가 스택 객체의 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()'과 관련이 있다고 확신했다. (나는 복사체를 오버로드해야했기 때문에 문제를 붙잡을 수 없었기 때문에 thread 대신 pointer-to-thread를 시도했지만 이상한 참조 카운트 오류가 발생했습니다). 하지만 나는 빗 나간다 ... 고맙습니다! – ahpoblete

관련 문제