[Interest] Threading Question

Constantin Makshin cmakshin at gmail.com
Thu Oct 9 17:01:05 CEST 2014


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20141009/2f318acc/attachment.html>


More information about the Interest mailing list