2014-11-29 7 views
1

현재 mutexCOM이라는 공유 뮤텍스를 사용하여 두 개의 boost::thread이 CPU에서 동일한 처리 시간을 얻으려고합니다. 현재 두 스레드는 무한대로 실행되도록 설정되어 있습니다. 한 스레드 (주 스레드)는 단순히 "테스트!" Navigation::begin() 기능을 실행하는 다른 스레드는 "----- 공유 기능 -----"을 인쇄하고 1 초를 기다린 후 "----- 공유 기능이 이제 끝납니다 ..." - ". 대기는이 스텁을 대체 할 함수에 필요한 많은 양의 처리를 시뮬레이트하기위한 것입니다. 무한 루프의 각 반복은 mutexCOM의 범위 잠금에 의해 루프 내에서 선행됩니다.뮤텍스 관리 스레드가 인터레이스 대신 "청크"로 처리되었습니다.

Thread staggering

`

이 보인다 :

testing! 
-----shared function----- 
----Shared function will now end...----- 
testing! 
-----shared function----- 
----Shared function will now end...----- 

불행하게도, 내가했던 것을 대신 할 출력을 발생합니다 예상 출력은 다음과 무한히 같은 것을해야한다 이 반복은 내가 기대했던 것처럼 인터레이스되는 대신 그룹으로 묶여있다. 누군가가 여기에 무슨 일이 일어나고 있는지 설명 할 수 있다면, 뮤텍스를 사용하는 쓰레드 관리에 대한 나의 이해가 어떤 일을 할 수있는 것 같아서, 나는 매우 감사하게 여길 것이다.

내 유일한 이론은 뮤텍스를 잠그기위한 대기열 처리가 잘못되었다는 나의 가정이 잘못되었으며 기아를 피하기 위해 스레드에 공정한 액세스 권한을 부여하기 위해 자체적으로 대기열을 만들어야한다는 것입니다. 그러나 나는 이것이 모든 관리를 독자적으로 처리해야하므로 뮤텍스를 근본적으로 왜곡시킬 것이기 때문에이 점에 대해서는 의문의 여지가 있습니다. 그 시점에서 세마포어를 사용하지 않는 이유는 무엇입니까?

내 코드는 다음과 같습니다. 관련 코드 만 포함되므로 누락 된 클래스 구조에 대해 걱정할 필요가 없습니다. 두 클래스의 모든 헤더가 제대로 포함되어 있으며 그 SharedMutex.h이 포함되어 가정 :

SharedMutex.h -

#ifndef SHARED_MUTEX_ 
#define SHARED_MUTEX_ 
#include <boost/thread/mutex.hpp> 
extern boost::mutex mutexCOM; 
#endif 

Navigation.cpp을 -

Navigation::begin() { 
    boost::mutex::scoped_lock lock(mutexCOM); 
    cout<< "-----shared function-----" << endl; 
    sleep(1); 
    cout<< "----Shared function will now end...-----" << endl; 
} 

mainclass.cpp -

void mainclass::run() { 
    this->runNav(); 
    while(1) { 
     boost::mutex::scoped_lock lock(mutexCOM); 
     cout << "testing!" << endl; 
    } 
} 
void mainclass::runNav() { 
//this->nav is an instance of Navigation within mainclass 
boost::thread navThread(boost::bind(&Navigation::begin, *(this->nav))); 
//this->navPtr is a pointer to the boost::thread for later management 
this->navPtr=&navThread; 
} 
+0

컨트롤이 방금 전달 될 것이라는 보장은 없습니다. 한 스레드에서 다른 스레드로. 나는 당신의 navThread에 대한 조건 기다림을 소개 할 것이고 주 스레드가 그것이 완료되었다는 신호를 보내 줄 것이다. – AlexanderVX

+0

어떻게 스레드간에 신호를 보내겠습니까? 뮤텍스를 통해이 작업을 수행 할 수 있습니까? 또한 mutexes FIFO 큐를이 정확한 시나리오를 처리하기위한 포함 된 것이라고 생각했습니다. – SwarthyMantooth

+2

세마포는 해당 prefered 메서드가 될 것입니다. – foips

답변

3

잘못되었습니다 :

// this->navPtr is a pointer to the boost::thread for later management 
    this->navPtr = &navThread; 

로컬 변수의 주소를 가져옵니다. 나중에 navPtr을 사용하면 정의되지 않은 동작입니다. 대신 멤버에 스레드를 저장하십시오. 아래 샘플을 참조하십시오. 난 아직 실제로 내 자신의

에 관리를 모두 처리 할 필요로 기본적으로 논쟁 뮤텍스의 점을 렌더링하기 때문

그러나 나는 이것에 대해 의심입니다. 작업 대기열을 원할 경우 작성하십시오. 뮤텍스는 그렇지 않습니다. 이름에서 알 수 있듯이, 뮤텍스는 단지 상호 배제에 대한 코드의 두 블록합니다 (중요한 부분)이 동시에 하지 실행을 수행하는 것이 기본 보장.

다른 어떤 것도 보장하지 않습니다. 수율을 도입하여 도시 될 수

스레드 부족이 실제로 문제/몇 시간 잔 :

Live On Coliru

#include <boost/thread.hpp> 
#include <boost/thread/mutex.hpp> 
#include <boost/scoped_ptr.hpp> 
#include <iostream> 

static boost::mutex mutexCOM; 

struct Navigation { 
    void begin() { 
     size_t count = 0; 
     while(++count< 10) { 
      { 
       boost::mutex::scoped_lock lock(mutexCOM); 
       std::cout << "-----shared function-----" << std::endl; 
       boost::this_thread::sleep_for(boost::chrono::milliseconds(200)); 
       std::cout << "----Shared function will now end...-----" << std::endl; 
      } 
      boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); // or boost::this_thread::yield e.g. 
     } 
     std::cout << "Navigation::begin() completed\n"; 
    } 
}; 

struct mainclass { 
    void run() { 
     size_t count = 0; 
     this->runNav(); 
     while (++count < (1ull<<20)) 
     { 
      { 
       boost::mutex::scoped_lock lock(mutexCOM); 
       std::cout << "testing!" << std::endl; 
      } 

      boost::this_thread::yield(); 
     } 
     std::cout << "mainclass::run() completed\n"; 
    } 

    ~mainclass() { 
     if (navThread.joinable()) 
     { 
      std::cout << "Waiting for Navigation to end...\n"; 
      navThread.join(); 
     } 
    } 
    private: 
    void runNav() { 
     navThread = boost::thread(boost::bind(&Navigation::begin, *(this->nav))); 
    } 

    boost::scoped_ptr<Navigation> nav { new Navigation }; 
    boost::thread navThread; 
}; 

int main() { 
    mainclass instance; 
    instance.run(); 
} 

인쇄 어느 : ./a.out | uniq -c

 1 testing! 
     1 -----shared function----- 
     1 ----Shared function will now end...----- 
    9726 testing! 
     1 -----shared function----- 
     1 ----Shared function will now end...----- 
    5501 testing! 
     1 -----shared function----- 
     1 ----Shared function will now end...----- 
    5197 testing! 
     1 -----shared function----- 
     1 ----Shared function will now end...----- 
    5316 testing! 
     1 -----shared function----- 
     1 ----Shared function will now end...----- 
    5913 testing! 
     1 -----shared function----- 
     1 ----Shared function will now end...----- 
    5515 testing! 
     1 -----shared function----- 
     1 ----Shared function will now end...----- 
    5639 testing! 
     1 -----shared function----- 
     1 ----Shared function will now end...----- 
    5352 testing! 
     1 -----shared function----- 
     1 ----Shared function will now end...----- 
    5162 testing! 
     1 Navigation::begin() completed 
995253 testing! 
     1 mainclass::run() completed 
     1 Waiting for Navigation to end... 
+0

아, 내 말에 잘못된 정보 인 것처럼 보입니다. 그 예를 쓰는 데 어려움을 겪어 줘서 고마워. – SwarthyMantooth

+0

@ SwarthyMantooth가 환호합니다! 나는 단지 형식이 잘못된 출력도 수정했다 : / – sehe