2017-08-11 8 views
0

QThreadの中にstd::condition_variableを使用する際に現在問題が発生しています。 QThread::run()メソッド内でnofity_oneまたはnotify_allとコールすると、スレッドがクラッシュします(「スレッドがまだ実行されている間はQThread:破棄されます」)。QThread :: run()内のstd :: condition_variableの使用

class ThreadImpl : public QThread 
{ 
    Q_OBJECT 

public: 
    ThreadImpl(QObject* parent = 0); 

    std::shared_ptr<std::mutex> GetMutexEventIsInit(); 

    std::condition_variable m_isInit; 

protected: 
    void run(); 

private: 
    mutable std::shared_ptr<std::mutex> m_pMutexEventIsInit; 
    mutable QMutex m_mutexPtrConnection; 

}; 


void AWSIoTConnectionUserRunner::run() 
{ 
    cout << DBGFUNC_CPP << endl; 
    { 
     // do init work here 

     // inform all 'waiters' that connection is initialized 
     m_isInit.notify_one(); 
    } 

    exec();  // <-- crashes here inside event-loop 

    cout << DBGFUNC_CPP << "- quits." << endl; 
} 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    ThreadImpl impl; 
    impl.start(); 

    // wait for connection to init 
    shared_ptr<mutex> pMutexUserConnectionInit = impl.GetMutexEventIsInit(); 
    { 
     unique_lock<mutex> lock(*pMutexUserConnectionInit); 
     runnerUserConnection.m_isInit.wait(lock); 
    } 
    cout << "This text never appears, because my program crashes before with:" << endl; 
    cout << "QThread: Destroyed while thread is still running" 
} 

が、私はこのことについてはQWaitConditionがあることを知っているが、それはSTLのいずれかで動作しない理由を私は得ることはありません。また、私は、スレッドによって作成されたものではなく、私が知っている限り、スレッドで安全でなければならない要素がアクセスされたためにクラッシュが発生したとも仮定しています。

私のコードで何が間違っているかご存知ですか?

ご協力いただきありがとうございます。

+0

Qtの管理スレッドは、標準スレッドとは何の関係もありません。それが条件変数が機能しない理由です。 ところで、あなたのスレッド管理は間違っています。 QThreadは、 から継承されるわけではありません http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/ –

+2

あなたのプログラムが 'cout << 'ステートメントを実行しますが、その後すぐにクラッシュするため、出力にはランタイムバッファから実際のコンソールに到達する機会がありません。 'main'を終了させ、ローカルの' impl'変数を破棄します。スレッドはまだ実行中です。 –

+0

@IgorTandetnikあなたの答えをありがとう。私はちょうど私が大きな間違いをしたことに気づいた。私は 'QCoreApplication :: exec()'コールをmyain関数の最後にコメントアウトしました。あなたの答えは正しい。 –

答えて

1

@IgorTandetnikのコメントは私を助けました。 私の主な機能の最後にQCoreApplication::exec()に電話するのを忘れました。

これは、すでに削除されたオブジェクトにアクセスするQtイベントループを引き起こす作業をする前に、メイン関数が有効範​​囲外になってスレッドが強制終了されるという現象につながりました。

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    ThreadImpl1impl; 
    impl.start(); 

    // wait for connection to init 
    shared_ptr<mutex> pMutexUserConnectionInit = impl.GetMutexEventIsInit(); 
    { 
     unique_lock<mutex> lock(*pMutexUserConnectionInit); 
     runnerUserConnection.m_isInit.wait(lock); 
    } 
    cout << "This text never appears, because my program crashes before with:" << endl; 
    cout << "QThread: Destroyed while thread is still running" 

    // This is what I forgot: 
    return a.exec(); 
} 
関連する問題