2014-04-25 3 views
1

현재 MSVC에서 개발 된 리눅스에 우리의 C++ Qt 응용 프로그램을 포팅하고 있으며 일부 스레딩 작업이 멈추지 않습니다. 창문에서는 모든 것이 잘 작동합니다.boost :: thread :: join 리눅스 응용 프로그램 동결

thread.h :

class our_thread 
{ 
    public: 
     our_thread(); 
     ~our_thread(); 

     void run(boost::thread*); 
     void join(const char* = 0); 
     inline bool is_running() const; 

    private: 
     void delete_thread(); 

     bool thread_is_running; 
     boost::thread* thread_object; 
}; 

thread.cpp :

void our_thread::run(boost::thread* t) 
{ 
    this->delete_thread(); 
    this->thread_object = t; 
    this->thread_is_running = true; 
    QApplication::setOverrideCursor(Qt::BusyCursor); 
    plot("in run"); 
} 

void our_thread::join(const char* text) 
{ 
    plot("in join"); 
    if(this->thread_object == 0) { return; } 
    this->thread_is_running = false; 
    QApplication::restoreOverrideCursor(); 
    if(text) 
    { 
     plot(text); 
    } 
    progress.show(false); 
    this->thread_object->join(); 
    this->delete_thread(); 
} 

void our_thread::delete_thread() 
{ 
    this->thread_is_running = false; 
    delete this->thread_object; 
    this->thread_object = 0; 
} 

및 예를 들어 전화 :

우리의 스레드 구현은 다음 코드 (발췌)를 사용
this->do_something_thread.run(new boost::thread(&function_name, this, param1)); 
... 
this->do_something_thread.join("Part creation finished"); 

plot() 호출은 사용자 정보이지만 디버그 출력에도 사용됩니다.

일부 작업의 경우이 절차가 항상 작동합니다. 스레드의 코드가 모두 끝나고 join()이 호출되면 항상이 프로그램이 고정됩니다. 소프트웨어를 디버깅하고 코드를 단계별로 실행하면 스레드를 다시 사용할 때까지 완벽하게 작동합니다. 그런 다음 run() 전화로 바로 연결됩니다.

아무런 차이없이 1.39.0과 1.49.0을 시험해 보았습니다. 우리는 RedHat 5.4를 사용하고 있으며 모든 것은 gcc44로 컴파일됩니다.

편집 : 나는이 모든 것이 간단한 코드 오류라고 생각하지 않기 때문에 모든 것이 창에서 제대로 작동한다는 것을 강조하고 싶습니다. 일부 컴파일러 특정 설정이나 플래그 또는 그와 같은 버그를 만들 수 있습니다 뭐든 리눅스 특정 일을 더 비슷합니다.

+1

'this-> thread_object-> run()'을 호출하지 마십시오. thread_is_running의 목적은 무엇입니까? – UmNyobe

+0

** ** 모든 ** 동기화 프리미티브를 사용합니까? 하나의 예제처럼,'thread_is_running' 부울에 적용 할 수있는 컴파일러 최적화와 메모리 모델이 무엇인지 어떻게 알 수 있습니까? – mockinterface

+0

@mockinterface "thread_is_running"값은 호출자에게만 건드립니다. 따라서 "our_thread"객체가 항상 동일한 스레드에서 액세스되는 경우 왜 동기화가 수행됩니까? 어쨌든'thread_is_running'은이 코드의 쓰기 전용 변수입니다. – sehe

답변

0

문제는 우리가 스레드 자체에서 스레드에 참여하고 있다는 것이 었습니다. 버전 1.54에서는 이렇게하면 교착 상태가 발생한다는 예외가 발생합니다. 이러한 예외는 이전 버전에서는 발생하지 않습니다 (어떤 이유로 든 교착 상태가 발생하지 않음). 스레드 외부에서 조인을 호출 한 후 이제 정상적으로 작동합니다.

0

복잡한 수동 메모리 관리 및 중복 부울 플래그를 사용하는 이유가 표시되지 않습니다 (스레드가 있으면 결합해야하며 부울은 중복되고 사용되지 않습니다).

그러나 교착 상태가 발생하지는 않습니다.

여기 Live On Coliru

#include <boost/thread.hpp> 

void plot(std::string msg) 
{ 
    static boost::mutex mx; 
    boost::lock_guard<boost::mutex> lk(mx); 

    std::cout << msg << "\n"; 
} 

class our_thread 
{ 
    public: 
     our_thread() : thread_object(0), thread_is_running(false) {} 
     ~our_thread(){delete_thread();} 

     void run(boost::thread*); 
     void join(const char* = 0); 
     inline bool is_running() const; 

    private: 
     void delete_thread(); 

     bool thread_is_running; 
     boost::thread* thread_object; 
}; 

void our_thread::run(boost::thread* t) 
{ 
    this->delete_thread(); 
    this->thread_object = t; 
    this->thread_is_running = true; 
    plot("in run"); 
} 

void our_thread::join(const char* text) 
{ 
    plot("in join"); 
    if(this->thread_object == 0) { return; } 
    this->thread_is_running = false; 
    if(text) 
    { 
     plot(text); 
    } 
    plot("progress.show(false);"); 
    this->thread_object->join(); 
    this->delete_thread(); 
} 

void our_thread::delete_thread() 
{ 
    this->thread_is_running = false; 
    delete this->thread_object; 
    this->thread_object = 0; 
} 

void function_name(std::string param1) 
{ 
    plot("Enter function_name"); 
    plot(param1); 
    boost::this_thread::sleep_for(boost::chrono::seconds(3)); 
    plot("Leave function_name"); 
} 

int main() 
{ 
    our_thread do_something_thread; 
    do_something_thread.run(new boost::thread(&function_name, "param1")); 
    // ... 
    do_something_thread.join("Part creation finished"); 
} 

당신이 당신의 문제를 보여줍니다 최소한의 변화를 해결할 수는 "작업"이 표시 자체에 포함 된 버전이다? 그러면 어쩌면 당신은 그 원인을 발견 할 수 있습니다.

+0

답변 해 주셔서 감사합니다.하지만 "귀하의 문제를 보여주는 최소한의 변경 사항을 해결할 수 있습니까?" 우리는 항상'our_thread'에 대한 두 번의 호출만을 사용하고 일부 메소드에 대해서는 작동하지 않습니다. 왜냐하면 어떤 함수는 작동하지 않기 때문입니다. – Bowdzone

+0

그러면 내 프로그램이 "올바르게 작동하는지"확인할 수 있습니까? 문제가 발생할 때까지 응용 프로그램과 유사한 더 많은 것들을 소개하십시오. 그러면 문제를 알게되거나 정확하게 물어볼 것입니다. – sehe

+0

제가 시도해 볼 수는 있습니다 만, 스레드에서 세 번째 파트 라이브러리를 사용하여 광범위한 3 차원 기하 연산을 수행 할 때 그렇게 쉬운 일이 아니므로 포함이 필요한 경우 많이 있습니다. 아마도 금요일 오후에 질문을해서는 안됩니다 ^^ – Bowdzone