[Qt-interest] Is it safe to connect different threads by Qt::DirectConnection?
donglongchao
donglongchao at 163.com
Tue Dec 8 04:13:36 CET 2009
在2009-12-06,"Mihail Naydenov" <mlists at ymail.com> 写道:
>
>>>
>>>You should post some code, I (completely) fail to understand your configuration, and what the problem is.
>>
>>class workthread:QThread
>>{
>> public slot:
>> void slot_fun()
>> { some time-consuming code here;}
>>}
>>void workthread::run()
>>{
>> QTimer timer;
>> QObject::connect(&timer,SIGNAL(timeout()),this,SLOT(slot_fun()));
>> timer.start(...);
>>}
>>GUI thread(main thread)
>>int main(int argc,char *argv[])
>>{
>> mythread = new workthread;
>>}
>>So now I want the slot function slot_fun() to run in the work thread ,not in the GUI thread.According to the documents,if the fifth parameter is not set,slot_fun() will run in the GUI thread which will cause the UI unresponsive.If the fifth parameter is set to be Qt::DirectConnection, slot_run() will run in work thread.This is what I need.But I want to know if it is thred-safe to do like this or if there is a better way I do not know.
>
>
>It seams you misinterpreted the documentation.
>
>"The fifth" by itself, cannot change where (in which thread) the the slot is executed.
>Where it is executed depends on where the qobject "lives". In general qobjects live in the thread they are created in the first place until they are movedToThread.
>
>Now in your example you have two qobjects: workthread and QTimer
>
>You create workthread instance in main => mythread "lives" in the man (GUI) thread => all slots will be executed in the main thread.
>You create QTime instance in QThread::run() - all objects, created in QThread::run() live in a different thread (understandably, considering this is "the code to be ran on a different thread").
>
>Now, you indeed connect objects from diff. threads, but the other way around!
>
>You send (thread safe) requests "from a different thread" to be handled in the gui thread! (slot in a object, living in the main thread)
>
>Note, again however, no option in qobject::connect can possibly change the thread position of the objects. It is again the other way around - connect does not change the thread affinity of the objects - its changed based on it!
>(this is, AutoConnection (the default) will be "modified" to be Direct if objects are on the same thread, and Queued if on diff.)
>
>Anyway here is somewhat reversed (and working) example of your code that does do the heavy work in slot in a diff thread.
>It is reversed because it creates the timer in the main thread and an work-doing-object on another.
>
>#include <QtGui>
>
>class worker : public QObject
>{
> Q_OBJECT
>public slots:
> void slot_fun()
> {
> //some time-consuming code here
>
> for(int i=0; i < 1000; ++i)
> {
>
> if(i%100 == 0)
> qDebug()<<"doing work..."<<i;
> }
>
> }
>
>};
>
>#include "main.moc"
>
>int main(int argc, char *argv[])
>{
> QApplication a(argc, argv);
>
> QTimer timer;
>
> QThread workerthead;
> workerthead.connect(&a,SIGNAL(aboutToQuit()), SLOT(quit()));
>
> worker laborer;
> laborer.moveToThread(&workerthead);
> laborer.connect(&timer,SIGNAL(timeout()),SLOT(slot_fun()));
>
>
> timer.start();
> workerthead.start();
>
> QWidget ui;
> ui.show();
>
> bool result = a.exec();
> workerthead.wait();
> return result;
>}
>
>Now, its not necessary for QTimer to be in the main, the important thing is - through the live of the app you can aways (safely) call the fun_slot()
>from any object and from any thread and have work done in parallel !
>
Thank you very much,Mihail Naydenov.But I have another question here.According to the documents,If you are calling a function on an QObject subclass that doesn't live in the current thread and the object might receive events, you must protect all access to your QObject subclass's internal data with a mutex; otherwise, you may experience crashes or other undesired behavior.
If I connect a signal of GUI thread to a slot of another object lives in workthread by the fifth parameter set default ,do I need to protect the the object's internal datas when the slot access them?I think the slot will run in the workthread and the event loop of the workthread will manage this signal/event and handle the execution of the slot.It will not conflict with the other signal/event/slot of the workthread(I mean we do not need QMutex or something like that here).Is it right?
>AFAIK this is the only way to have work done in a slot on a diff thread.
>
>(again)
>At Qt team, please add at least one example about this technique!
>
>MihailNaydenov
>
>
>>>
>>>>...
>>>>
>>>>Longchao.
>>>>
>>>
>>>
>>>
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20091208/2bb76f32/attachment.html
More information about the Qt-interest-old
mailing list