[Interest] Threading Question

Jason Kretzer Jason at gocodigo.com
Thu Oct 9 13:05:40 CEST 2014


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





More information about the Interest mailing list