2

As suggested in this question, I am now trying to incorporate multithreading.

According to the links given by karlphillip, I understand that the documentation about subclassing QThread is not to be followed and to use moveToThread() as explained. Now I see that default implementation of QThread run() has only an exec() which must then be ended by calling quit() when worker thread has finished operations. I have a few questions now so that I understand things better:

QApplication* ptrApp=new QApplication(argc,argv);
QThread* th=new QThread;
MyClass* obj=new MyClass;
obj->moveToThread(th);
QObject::connect(th,SIGNAL(started()),obj,SLOT(someFunct()));
QObject::connect(obj,SIGNAL(over()),th,SLOT(quit()));
th->start();
//some GUI code in main thread here
return ptrApp->exec();
  1. What happens if I continue to use someFunct() even after I emit over() from within someFunct()? Is it undefined behaviour or normal?

  2. Which thread would obj now be associated with (while the rest of the code after emitting over() is still executing in someFunct)? My understanding is: it cannot be in th when I have quit() that thread... quit() will be queued until the exec() in the main thread executes it which will cause the exec() in run() of th to exit (I hope I am not making a mistake here). I assume that thread is no longer existent.

  3. Once slot quit() for th is executed, is it safe to assume that the thread has indeed quit or should I further connect finished() signal of th to some slot to be absolutely sure?

Community
  • 1
  • 1
ustulation
  • 3,600
  • 25
  • 50

2 Answers2

1
  1. It doesn't matter if the event loop is terminated, somefunct() will continue to run until it gives control back to the now extinct loop.

  2. obj stays associated to the thread, so if a signal connected to one of its slots is emitted, the slot won't run but it will be queued for when/if the thread is restarted.
    If the QThread object is deleted, obj->thread() returns 0, so I suppose this would be equivalent to calling obj->moveToThread(0) and according to the documentation:

    If targetThread is zero, all event processing for this object and its children stops.

  3. quit() terminates the event loop, then the finished() signal is emitted from the thread, and the thread terminates.
    So, even when you receive the finished() signal, you shouldn't assume that the thread is finished yet. You can use QThread::wait from the main thread, after you receive that signal to ensure that.
    If the thread is in the finishing state, the QThread destructor already calls wait, so you can safely delete the thread after the finished() signal (with deleteLater() to be even safer).

alexisdm
  • 29,448
  • 6
  • 64
  • 99
  • thanks 1. ya that's the behaviour i was noticing...just wanted to make sure it's not undefined/illegal or something 2. ok...pls tell me what happens if i delete the QThread pointer `th` (now as we cannot restart the thread anymore i suppose) 3. for `quit()` i understand that it will be in queue until `exec()` in the main thread executes it...but `finished()` is a signal which shouldn't require any event loop and it being the ultimate stuff to be done by the terminating thread, why is `QThread::wait()` required additionally as you point out once i make use of the `finished()` signal? – ustulation Mar 16 '12 at 11:59
  • For 2. you can stop and restart the thread as often as you want. And for 3. emitting a signal doesn't require an event loop. The slot to which you connect it should be in another thread with a running event loop anyway (the thread eventloop can't receive its own finished() signal). But after looking in the QThread's source, I think you can just wait for the finished signal in most cases. – alexisdm Mar 16 '12 at 14:21
0

1. What happens if I continue to use someFunct() even after I emit over() from within someFunct()? Is it undefined behaviour or normal?

As you are using direct connections, emitting over will call directly the function quit, which stops the event loop and return from the exec in the thread run method. Which means someFunct() will not finish its execution and the objects inside it are either lost or in a partial modified state.

2. Which thread would obj now be associated with (while the rest of the code after emitting over() is still executing in someFunct)?

As said previously somefunct will not finish its execution. But I believe any objects associated with this thread will remain as such. I say I believe because there is no solid assertion anywhere, but it make sense the most. As mentioned in the doc, for these objects to send or receive events the thread must be started again....

3. Once slot quit() for th is executed, is it safe to assume that the thread has indeed quit or should I further connect finished() signal of th to some slot to be absolutely sure?

quit() terminates the event loop and return where exec() was called.

Notice that the object Qthread is not the thread. so until you enter exec(), it is the main thread which is running... As well as it is the main thread which runs after the exec.

Anyway these are some great questions...

UmNyobe
  • 22,539
  • 9
  • 61
  • 90