[Qt-interest] [[Fwd: Re: QThread::run() running in wrong thread]]

K. Frank kfrank29.c at gmail.com
Mon May 24 01:57:43 CEST 2010


Hi Ove (and Thiago) -

On Sun, May 23, 2010 at 5:49 PM, Thiago Macieira <thiago at kde.org> wrote:
> Em Domingo 23. Maio 2010, às 18.22.39, Ove Fagerheim escreveu:
>> Sorry 'bout that, you're right of course. I took one shortcut to many.
>> ...
>
> In the example that you sent, after correcting the mistakes, I came up with
> the attached code. It doesn't produce any warnings when run.
>
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>  Senior Product Manager - Nokia, Qt Development Frameworks
> ...

I also tried my hand at massaging your example.  Everything seems
to work for me (at least the way I expect).  I tried not to change
anything you were doing with the threads.

(In my example, I just used a plain-vanilla main(), rather than the
QCoreApplication that Thiago used.  I'm not sure whether what I
did is legal Qt, but it seems to work.)

>>> Seems like th code really is running in main thread after all.

Hmm...  It looks like it works for me.  thr->run() runs in a thread that is
distinct from the main thread.  (See example, below.)

>>> I cant
>>> change affinity for m_worker in workerthread, due to wrong thread
>>> running.

This also works for me.  (See example, below.)

>>> class SomeObject;
>>> class WorkerThread : public QThread
>>>  {
>>> ...

When I run my version of your example, I get the follow output:

C:\thread_test.exe
main(): entering...
main(): QThread::currentThread() is 00522D40  <-- main thread
main(): thr->thread() is 00522D40
main(): parent->thread() is 00522D40
main(): p->thread() is 00522D40
main(): p->thread() is 00522B68
WorkerThread::run(): currentThread() is 00522B68   <-- different from
main thread
WorkerThread::run(): thread() is 00522D40  <-- thread affinity is for
main thread
WorkerThread::run(): obj->thread() is 00522B68
WorkerThread::run(): m_parent->thread() is 00522D40
WorkerThread::run(): m_worker->thread() is 00522B68
WorkerThread::run(): m_worker->thread() is 00522D40  <-- moveToThread succeeds
main(): exiting...

In my example code, the following two lines print out different values
for currentThread(), showing that thr->run() executes in a thread distinct
from the main thread:

   fprintf (stderr, "main(): QThread::currentThread() is %p\n",
QThread::currentThread());
   fprintf (stderr, "WorkerThread::run(): currentThread() is %p\n",
currentThread());

Also, the "before" and "after" print statements in the following code fragment
show that moveToThread succeeds in changing m_worker's thread affinity to
m_parent->thread():

   fprintf (stderr, "WorkerThread::run(): m_worker->thread() is %p\n",
m_worker->thread());
   // next statement failes due to code running in wrong thread --
looks like it succeeds...
   m_worker->moveToThread (m_parent->thread());
   fprintf (stderr, "WorkerThread::run(): m_worker->thread() is %p\n",
m_worker->thread());

The following example code compiles and runs cleanly for me, and generates
the output shown above.  (I'm using Qt 4.6.1 with 32-bit mingw using gcc 4.4.1
on 64-bit windows 7.)

*** example code ***

// thread_test.cpp

#include <cstdio>

#include <QObject>
#include <QThread>

class WorkerThread : public QThread {
  public:
    void create (QObject *pParam, QObject *pParent) {
      m_worker = pParam;
      m_parent = pParent;
    }
    void run() {
      // Next statement still reports wrong thread -- looks right to me...
      fprintf (stderr, "WorkerThread::run(): currentThread() is %p\n",
currentThread());
      fprintf (stderr, "WorkerThread::run(): thread() is %p\n", thread());
      QObject *obj = new QObject;
      fprintf (stderr, "WorkerThread::run(): obj->thread() is %p\n",
obj->thread());
      // do some work
      fprintf (stderr, "WorkerThread::run(): m_parent->thread() is
%p\n", m_parent->thread());
      fprintf (stderr, "WorkerThread::run(): m_worker->thread() is
%p\n", m_worker->thread());
      // next statement failes due to code running in wrong thread --
looks like it succeeds...
      m_worker->moveToThread (m_parent->thread());
      fprintf (stderr, "WorkerThread::run(): m_worker->thread() is
%p\n", m_worker->thread());
      // ...
    }
  private:
    QObject *m_worker;
    QObject *m_parent;
};

int main(int argc, char *argv[]) {
  fprintf (stderr, "main(): entering...\n");
  WorkerThread *thr = new WorkerThread();
  fprintf (stderr, "main(): QThread::currentThread() is %p\n",
QThread::currentThread());
  fprintf (stderr, "main(): thr->thread() is %p\n", thr->thread());
  QObject *parent = new QObject;
  fprintf (stderr, "main(): parent->thread() is %p\n", parent->thread());
  QObject *p = new QObject;
  fprintf (stderr, "main(): p->thread() is %p\n", p->thread());
  p->moveToThread (thr);
  fprintf (stderr, "main(): p->thread() is %p\n", p->thread());
  thr->create (p, parent);
  thr->start();
  while (!thr->isFinished());  // wait for thread to finish
  fprintf (stderr, "main(): exiting...\n");
}

*** end of example ***


Good luck.


K. Frank


>>> ...
>>>
>>> best regards
>>> Ove
>>> ...




More information about the Qt-interest-old mailing list