2017-08-11 45 views
0

我目前在QThread内使用std::condition_variable时遇到问题。 当我在QThread::run()方法内调用nofity_onenotify_all时,我的线程崩溃(“线程仍在运行时,QThread:销毁”)。std :: condition_variable QThread :: run()内部的用法

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的工作之一。此外,我还假设崩溃是由于一个元素被访问而不是由线程创建的,但据我所知std::condition_variable应该是线程安全的。

你知道我的代码有什么问题吗?

在此先感谢您的帮助!

+0

我不知道,但也许是如何管理线程在Qt中与std线程无关。这就是为什么条件变量不起作用。 顺便说一下,你的线程管理是错误的。 QThread是不是意味着要继承 http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/ –

+2

我怀疑你的程序确实达到'cout << ... '语句,但因为此后不久崩溃,输出没有机会从运行时缓冲区中获取到实际控制台上。您允许'main'终止,并在线程仍在运行时销毁本地'impl'变量。 –

+0

@IgorTandetnik谢谢你的回答。我只是意识到我犯了一个巨大的错误。我在'main'函数的结尾注释了'QCoreApplication :: exec()'调用。所以你的回答是正确的。 –

回答

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(); 
} 
相关问题