[Interest] Threading Question
Constantin Makshin
cmakshin at gmail.com
Thu Oct 9 06:11:57 CEST 2014
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);
>> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20141009/57146f1c/attachment.sig>
More information about the Interest
mailing list