c++ - Qt GUI doesn't work with std::thread as I expect -
the core of project independent of gui framework that's why prefer std::thread. qt gives me error when thread using.
the inferior stopped because received signal operating system.
signal name: sigsegv
signal meaning: segmentation fault
//mainwindow.h #ifndef mainwindow_h #define mainwindow_h #include <thread> #include <mutex> #include <qmainwindow> namespace ui { class mainwindow; } struct observer { virtual void notify() = 0; }; class core { public: std::thread *run() { std::thread thread(&core::runp, this); thread.detach(); return &thread; } void setobserver(observer *observer) { _observer = observer; } int ii() const { return _ii; } void nextii() { _ii++; } void lock() { _mutex.lock(); } bool trylock() { return _mutex.try_lock(); } void unlock() { _mutex.unlock(); } private: void runp() { (int = 1; <= 1000; i++) { if (i % 10 == 0) { lock(); nextii(); unlock(); notify(); } } } void notify() { _observer->notify(); } //!!! observer *_observer; int _ii; std::mutex _mutex; }; struct mwobserver : public observer { explicit mwobserver(struct mainwindow *mainwindow) { _mainwindow = mainwindow; } virtual void notify(); mainwindow *_mainwindow; }; class mainwindow : public qmainwindow { q_object public: explicit mainwindow(qwidget *parent = 0); ~mainwindow() { delete _ui; } void upd(); public slots: void run() { _core.run(); } private: ui::mainwindow *_ui; mwobserver _observer; core _core; }; inline void mwobserver::notify() { _mainwindow->upd(); } #endif
-
//mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" mainwindow::mainwindow(qwidget *parent) : qmainwindow(parent), _ui(new ui::mainwindow), _observer(this) { _ui->setupui(this); connect(_ui->pushbuttonrun, signal(clicked(bool)), this, slot(run())); } void mainwindow::upd() { _core.lock(); setwindowtitle(qstring::number(_core.ii())); _core.unlock(); }
there multiple problems here, first , obvious noted perencia. returning pointer stack variable. in c++ terms it's unacceptable.
secondly. crash comes not using std::thread
, race condition. qt event loop not know mutex, setwindowtitle
call introducing race, leads crash. need use qmetaobject::invokemethod post function qts event loop.
example: change
inline void mwobserver::notify() { _mainwindow->upd(); }
to
inline void mwobserver::notify() { if(!qmetaobject::invokemethod(_mainwindow, "upd", qt::queuedconnection)) std::cerr << " failed invoke method" << std::endl; }
additional includes may apply
Comments
Post a Comment