2012-04-01 4 views
0

저는 GUI 응용 프로그램 인 작은 응용 프로그램을 구현하려고하는데, 그 중 하나가 주요 작업 중 하나입니다. 분명히 나는이 "작업"을 별도의 스레드에 넣고이 스레드에서 start fnc를 호출하여이 스레드를 시작합니다. 불행히도 아무 일도 일어나지 않습니다. 다른 한편으로는 시작 대신에 구현 된 fnc 실행 계산을 수행해야합니다. 물론 gui와 같은 스레드에서 수행해야합니다. 무엇을해야합니까?
는 그래서 클래스 QThread 상속이 있습니다start가 실행을 호출하지 않습니다.

class Working_Thread : public QThread 
{ 
    Q_OBJECT 
public: 
    typedef boost::filesystem3::path path_t; 

private: 
    bool& cancel_flag_; 
    const std::set<path_t>& paths_; 
    int search_depth_; 
    typedef void (Dir_File_Select_Dialog::*fnc_ptr)(const std::set<path_t>&,int); 
    fnc_ptr fnc_; 
    Dir_File_Select_Dialog* parent_; 
protected: 
    void run() 
    { 

     (parent_->*fnc_)(paths_,search_depth_); 
    } 
public: 

    Working_Thread(bool& cancel_flag,const std::set<path_t>&,int&,fnc_ptr fnc,Dir_File_Select_Dialog* parent); 


}; 

을 내가 새 스레드를 시작하려고 할 때 여기에 조각 GUI 스레드에서입니다 :

Working_Thread* working_thread = new Working_Thread(cancel_flag,paths,search_depth,&Dir_File_Select_Dialog::extract_files_,this); 
     working_thread->start();//this desn't invoke run fnc 

을하지만 난 할 때

working_thread->run();//this will perform computations although in gui thread 

업데이트 :
약간의 변경 이제 시작 fnc를 사용할 때 계산을 수행하지만 여전히 GUI를 차단합니다.

Working_Thread* working_thread = new Working_Thread(cancel_flag,paths,search_depth,&Dir_File_Select_Dialog::extract_files_,this); 
    working_thread->start();//hangs 
    working_thread->wait();//when I call wait here computation is performed but GUI is blocked. 
+0

일부 노트 : 1. 어떻게 너는 이해하고 있니? 2. GUI 객체가 계산을 수행하는 이유는 무엇입니까? 그들은 GUI와 연결되어 있습니까? 모든 GUI 작업은 GUI 스레드에서 호출되어야하며 Qt의 모든 부분은 스레드로부터 안전하지 않다는 것을 알고 계십니까? – Lol4t0

+0

@ Lol4t0 1. 아무런 효과가 보이지 않기 때문에 실행되지 않았습니다. 직접 실행할 때와 달리보기에 결과가 표시되지 않습니다. 2. Gui는 계산을 수행하지 않습니다. 어디에서이 점을 이해 했습니까? 그렇습니다. 이해합니다. – smallB

+0

간단한 디버그 출력을 함수에 추가하여 확인하십시오. 보기를 변경하려면 이미 다른 스레드에서 Gui가 변경 중이라는 의미입니다. – Lol4t0

답변

1

난 당신의 코드가 실제로 수행하는 방법을 모르겠지만, 첫 번째 단계로 내가 제안 QThread의 Qt는 문서의 새로운 버전의 끝에있는 최선의 방법을 따르도록 당신을 제안 대부분의 (http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

내가 직접 내가 스레드 큰 문제가 끝내 QThread 내 처리를 만들려고 할 때마다 : 당신이이 기사를 확인할 수있는 유사한 튜토리얼이 페이지의 하단)

를 찾아 시간, 호출자의 트레드에서 수행되는 beeing). 이 설명서는 4.8에서 추가되었으며 이전 버전의 설명서에서 제공 한 예제는 실종되었습니다.

(Qt의 문서에서 복사 한 코드) QThread 사용하는 기본 방법으로 다음과 같은 패턴을 고려 : 또는

class Worker : public QObject 
{ 
Q_OBJECT 

public slots: 
void doWork() { 
/* ... */ 
} 
}; 

/* ... */ 
QThread *thread = new QThread; 
Worker *worker = new Worker; 
//obj is a pointer to a QObject that will trigger the work to start. It could just be this 
connect(obj, SIGNAL(startWork()), worker, SLOT(doWork())); 
worker->moveToThread(thread); 
thread->start(); 
//obj will need to emit startWork() to get the work going. 

을, 당신은 할 수 :

//based on the same Worker class as above: 

/* ... */ 
QThread *thread = new QThread; 
Worker *worker = new Worker; 
worker->moveToThread(thread); 
thread->start(); 
QMetaObject::invokeMethod(worker, "doWork", Qt::QueuedConnection); 
+0

# 마르크 안녕, 당신의 대답에 감사드립니다. 그 두 웹 사이트를 읽은 후에도 그 주제에 대한 결론이 하나도 없다는 사실 때문에 나는 여전히 혼란 스럽다. – smallB

+0

#smallB이 주제가 잘못된 솔루션으로 이어지는 구식의 많은 문서와 상당히 혼동된다고 동의했습니다. 그래도 기존 코드를이 아키텍처로 전환하면 자신과 비슷한 많은 문제를 해결할 수 있습니다. 건배! – Marc

1

이 완료 될 때까지 스레드를 대기하므로 GUI 블록 당신이 스레드에 대기()를 호출하는 경우, 또한이 경우 대기에 대한 제한 시간을 지정하지 않은 것이 정상입니다.

초기 문제 (wait()를 호출하지 않을 때)와 비슷한 시나리오에서 QThread를 성공적으로 사용했습니다. 난 당신의 코드에서 어떤 문제가 있는지하지만 알고 있지만 실행은 그래서 어쩌면 일부 로그/디버그 메시지 전에 삽입

(parent_->*fnc_)(paths_,search_depth_); 

의 호출에 같은 다른 곳에서 정지하지 않는 경우 내가 무엇을 체크 할 것은 없습니다 그리고이 호출 후에 여기에서 호출되는 함수에서 문제를 격리하는 데 도움이 될 수 있습니다. 적어도 run() 메서드가 호출되는지 여부는 알 수 있습니다. 예를 들어 :

qDebug() << "In thread.run()"; 
(parent_->*fnc_)(paths_,search_depth_); 
qDebug() << "In thread.run(), calculations are done"; 

또한 나는 의심스러운 당신이 GUI 개체 (Dir_File_Select_Dialog)를 사용하여 계산을 수행 할 것을 찾을 수 있습니다. 이것은 Qt에서는 정상이 아니며 Gui 객체는 일반적으로 GUI 스레드에서 사용해야합니다. 계산을 실행 중에 직접 구현하지 않겠습니까? 또는 적어도 GUI가 아닌 객체로 이동하여 GUI 구현이 백그라운드 작업과 분리되도록하십시오.

0

대기 호출하면 GUI가 차단됩니다.

시작시이 프로그램이 중단되면이 호출에 문제가있는 것 같습니다. (parent_->*fnc_)(paths_,search_depth_); 이 호출 전후에 qDebug 호출을 배치 할 수 있습니다. (

http://qt-project.org/doc/qt-4.8/QThread.html :

관련 문제