You're right, but the original Jason's message contains this fragment: > 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);
So the timer is created on the heap as a child of BackgroundClass object and therefore will/should be moved along with that object. On 10/10/2014 08:48 PM, Alan Ezust wrote: > 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 <cmaks...@gmail.com > <mailto:cmaks...@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" <ja...@gocodigo.com > <mailto:ja...@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....@qt-project.org > <mailto:gocodigo....@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@qt- > > project.org <http://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 <ja...@gocodigo.com > <mailto:ja...@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
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest