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

Popular posts from this blog

html - Styling progress bar with inline style -

java - Oracle Sql developer error: could not install some modules -

How to use autoclose brackets in Jupyter notebook? -