0

I want to write some class which has to work in own thread. I've read this article: http://wiki.qt.io/Threads_Events_QObjects. It advises to move object which has to work in own thread, like:

TestClass tst;
QThread *thread = new QThread();
tst.moveToThread(thread);
thread->start();
QObject::connect(thread, SIGNAL(started()), &tst, SLOT(start()));

And in slot of TestClass I put all initializations procedures. 1. Can I moveToThread in TestClass' constructor? Like:

TestClass::TestClass() {
  QThread *thread = new QThread();
  this->moveToThread(thread);
  thread->start();  
  QObject::connect(thread, SIGNAL(started()), this, SLOT(start()));
}

After that all objects of this class will be working in own threads.

  1. In TestClass I have private struct which can be changed in both threads. Should I use mutex for that or use signal/slots:

    void TestClass::changeStruct(int newValue) {
      // invoked in main thread
    
      emit this->changeValue(newValue);
    
    }
    
    // slot
    void TestClass::changeStructSlot(int newValue) {
      // this slot will be invoked in the second thread
      this._struct.val = newValue;
    }
    
Mike
  • 860
  • 14
  • 24
  • Why have a function that just emits a signal, why not connect a signal to `TestClass::changeStructSlot` and emit that signal where you call `TestClass::changeStruct`, or call [`QMetaMethod::invoke`](http://doc.qt.io/qt-5/qmetamethod.html#invoke) / [`QMetaObject::invokeMethod`](http://doc.qt.io/qt-5/qmetaobject.html#invokeMethod). – thuga Mar 02 '16 at 07:54
  • Better connect `SIGNAL(start())` before starting the thread, or you risk missing the signal by a race condition. – Johannes Schaub - litb Mar 02 '16 at 12:42

1 Answers1

1
  1. I wouldn't do it at least from the design point of view. On top of what TestClass is supposed to do you try to add internal thread management. Also TestClass destructor is going to be little bit complicated because of thread management.

  2. Every TestClass object has its own struct. If the call from main thread is the only way to change val then nothing has to be done. If the val can be changed from more than 1 thread including its own then use QMutex.

StahlRat
  • 1,199
  • 13
  • 25
  • 2. So if I will use slots/signals how I've written above that means that method can be invoked in an any threads but `slot` (`changeStructSlot`) always will be executed in thread of TestClass, isn't? – Mike Mar 01 '16 at 18:44
  • Correct. And it should be no concurrency unless you decide do not use default connection type. This page explains details: [Signals and Slots Across Threads](http://doc.qt.io/qt-4.8/threads-qobject.html#signals-and-slots-across-threads) – StahlRat Mar 01 '16 at 19:11
  • Then I think it will be more easy way. Will not use `mutex`. `TestClass::TestClass() { /* default type connection - Auto Connection. */ connect(this, SIGNAL(changeValue(int)), this, SLOT(changeStructSlot(int))); /* other stuff */ } void TestClass::changeStruct(int newValue) { /* this method can be invoked in an any thread */ emit this->changeValue(newValue); }` right? – Mike Mar 01 '16 at 19:26
  • Yes, this or direct call `emit TestClassObject->changeValue(newValue);` should work and no need for mutex because of Auto Connection. – StahlRat Mar 01 '16 at 19:36