[Interest] Threading Question

Alan Ezust alan.ezust at gmail.com
Fri Oct 10 18:48:53 CEST 2014


>From what I understand, moveToThread() requires a parent-child relationship
between the objects for the "subtree" to include them.

If the QTimer was a subobject (data member) rather than a pointer to
another heap object with the parent set, then the QTimer won't be moved to
the other thread along with the containing object (!). Certain complex Qt
objects can't moved properly to another thread because of this reason.



On Thu, Oct 9, 2014 at 8:01 AM, Constantin Makshin <cmakshin at gmail.com>
wrote:

> The description of QObject::moveToThread() says the whole object's
> "subtree" is moved, so that hypothesis doesn't sound very plausible.
> On Oct 9, 2014 3:06 PM, "Jason Kretzer" <Jason at gocodigo.com> wrote:
>
>> Ack!  You are correct.
>>
>> I guess I would do something like this to remedy that:
>>
>> in the main:
>> BackgroundTaskManager::init();
>>     QThread *thread = new QThread();
>>     connect(thread, SIGNAL(started()), BackgroundTaskManager::instance(),
>> SLOT(startTimer()));
>>     BackgroundTaskManager::instance()->moveToThread(thread);
>>     thread->start();
>>
>> where the SLOT startTimer would instantiate that QTimer that was
>> previously in the constructor.
>>
>> correct?
>>
>> -Jason
>>
>> On Oct 9, 2014, at 6:46 AM, interest-bounces+jason=
>> gocodigo.com at qt-project.org wrote:
>>
>> >
>> > On Thursday 09 October 2014 03:32:20 Jason Kretzer wrote:
>> >> Thanks for the response.
>> >>
>> >> Yeah, I have placed qDebug() just before and just after the emit.  The
>> one
>> >> before always prints, the one after never does except in the following
>> >> case.  If I change the connection to QueuedConnection, then the qDebug
>> >> right after does print, the rest of the function does return and the
>> next
>> >> iteration of the while loop does start.  However, in the slot, as soon
>> as
>> >> it starts to execute, the loop literally stops executing at another
>> spot.
>> >> This leads to the same condition, the mutex is never released.
>> >>
>> >> The idea is that the BackgroundClass just be executing on its own
>> while the
>> >> main thread (Thread A) is off doing what it does.
>> >>
>> >> Is it possible that the program flow of BackgroundClass is being
>> pulled back
>> >> into the main thread when the slot starts executing and is thus
>> waiting its
>> >> turn?
>> >>
>> >> -Jason
>> >>
>> >> On Oct 9, 2014, at 12:11 AM, interest-bounces+jason=gocodigo.com at qt-
>> > project.org wrote:
>> >>> Two suggestions:
>> >>> 1) add qDebug-s around the "emit someSignal();" line to see whether it
>> >>> returns or not, hanging somewhere in validateResult();
>> >>> 2) try to explicitly specify the Qt::QueuedConnection type for the
>> >>> someSignal() connection — if it helps, then the [most likely] cause is
>> >>> Qt choosing wrong connection type.
>> >>>
>> >>> And, as always, a minimal compilable example would be nice. :)
>> >>>
>> >>> On 10/09/2014 07:53 AM, Jason Kretzer wrote:
>> >>>> Addendum at the bottom…
>> >>>>
>> >>>> On Oct 8, 2014, at 11:42 PM, Jason Kretzer <Jason at gocodigo.com>
>> wrote:
>> >>>>> I am a bit confused on threading.
>> >>>>>
>> >>>>> Lets say I have Thread A — which is where the program is started —
>> has
>> >>>>> main(), etc.
>> >>>>>
>> >>>>> Inside of main() I instantiate a class called BackgroundClass and I
>> move
>> >>>>> it to another thread (Thread B).>>>
>> >>>>>   BackgroundClass::init();
>> >>>>>
>> >>>>>   QThread *thread = new QThread();
>> >>>>>   BackgroundClass::instance()->moveToThread(thread);
>> >>>>>   thread->start();
>> >>>>>
>> >>>>> Inside of BackgroundClass in the constructor, I start a QTimer that
>> is
>> >>>>> supposed to go off every 5minutes and call the runTasks function
>> when
>> >>>>> it does. QTimer* timer = new QTimer(this);
>> >
>> > And in _which_ thread does this happen? I would guess the constructor is
>> > running in the main thread. So you create the timer there, too.
>> > Later you move your BackgroundClass to the other thread, but the timer
>> stays
>> > where it was created.
>> >
>> >>>>>
>> >>>>>  connect(timer, SIGNAL(timeout()), this, SLOT(runTasks()));
>> >>>>>  timer->start(FIVE_MINS);
>> >>>>>
>> >>>>> I put a qDebug in the runTasks function to ensure that it is a
>> different
>> >>>>> thread than the main thread (Thread A). qDebug() << "Running
>> tasks...
>> >>>>> -- Thread ID: " << QThread::currentThreadId(); //inside runTasks
>> >>>>>
>> >>>>> This always shows a different ID than the main thread.
>> >>>>>
>> >>>>>
>> >>>>> Back in the main thread (Thread A), I instantiate another class
>> AFTER
>> >>>>> the BackgroundClass instantiation.
>> >>>>>
>> >>>>> WorkManager::init();
>> >>>>>
>> >>>>> this is not moved to a separate thread so, I assume it stays in
>> Thread
>> >>>>> A.
>> >>>>>
>> >>>>> In the constructor of WorkManager, I connect Signals from
>> >>>>> BackgroundClass to Slots in WorkManager like so.
>> >>>>>
>> >>>>> connect(BackgroundTaskManager::instance(), SIGNAL(someSignal()),
>> >>>>> instance(), SLOT(restartWorker()));
>> >>>>>
>> >>>>> When the BackgroundClass finishes a task, it emits the someSignal.
>> >>>>>
>> >>>>>> From what I can tell, as soon as the someSignal is emitted, the
>> >>>>>> restartWorker slot is called and the rest of the code that is
>> >>>>>> immediately after that does not execute.  For example, above, the
>> >>>>>> runTasks function is supposed to run several tasks in a while loop.
>> >>>>>> To make sure this loop is thread safe, so it can be the only thing
>> >>>>>> running those tasks I put a mutex around the while loop.  At the
>> end
>> >>>>>> of the runTask function, the someSignal is emitted the result is
>> set,
>> >>>>>> and then it is returned.>>>
>> >>>>> if (!mutex.tryLock()) {
>> >>>>>
>> >>>>>          qDebug() << "Previous instance of RunTasks still
>> running...";
>> >>>>>          return;
>> >>>>>
>> >>>>>      }
>> >>>>>
>> >>>>> while(moreTasks) {
>> >>>>>
>> >>>>>   bool result = runTask(t);
>> >>>>>
>> >>>>>   updateDatabase(t, result);
>> >>>>>
>> >>>>> }
>> >>>>> mutex.unlock();
>> >>>>>
>> >>>>>
>> >>>>> Unforturnately, the runTask method never returns, it appears that
>> the
>> >>>>> restartWorker is called immediately upon someSignal being emitted.
>> >>>>>
>> >>>>> So, I say all that to ask, why does the rest of the code not
>> execute?
>> >>>>> Obviously, I am doing something wrong, but I am not sure where the
>> flaw
>> >>>>> is.  Would anyone be so kind as to point me in the right
>> direction?>>
>> >>>> ADDENDUM:
>> >>>> Since the runTask method never returns, the mutex is never
>> released.  So,
>> >>>> it stalls because the mutext is not released.
>> >>>>
>> >>>> Also, just to clarify, the end of runTask, looks like this:
>> >>>> …
>> >>>> ...
>> >>>> emit someSignal();
>> >>>> result = validateResult(); //last second validation
>> >>>> return result;
>> >>>> }
>> >>>>
>> >>>>
>> >>>> -Jason
>> >>>
>> >>> -----
>> >>> No virus found in this message.
>> >>> Checked by AVG - www.avg.com
>> >>> Version: 2014.0.4765 / Virus Database: 4015/8233 - Release Date:
>> 09/18/14
>> >>> Internal Virus Database is out of
>> >>> date.<signature.asc>_______________________________________________
>> >>> Interest mailing list
>> >>> Interest at qt-project.org
>> >>> http://lists.qt-project.org/mailman/listinfo/interest
>> >>
>> >> _______________________________________________
>> >> Interest mailing list
>> >> Interest at qt-project.org
>> >> http://lists.qt-project.org/mailman/listinfo/interest
>> >
>> > _______________________________________________
>> > Interest mailing list
>> > Interest at qt-project.org
>> > http://lists.qt-project.org/mailman/listinfo/interest
>>
>>
>> _______________________________________________
>> Interest mailing list
>> Interest at qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/interest
>>
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20141010/6140fa34/attachment.html>


More information about the Interest mailing list