Results 1 to 17 of 17

Thread: moveToThread and connecting Signals

  1. #1
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default moveToThread and connecting Signals

    Hello guys,

    I want to figure out the difference between connecting signals of an object before moveToThread and connecting signals after moveToThread method.

    Is it right that first assumption results in asynchron slot calls of mySlot and second results in synchron slot calls of mySlot?

    Qt Code:
    1. QThread* thread = new QThread();
    2. MyObject* object = new MyObject();
    3.  
    4. object->moveToThread(thread);
    5.  
    6. connect(object,SIGNAL(mySignal()),this,SLOT(mySlot())); // asynchronous
    7.  
    8. thread->start();
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. QThread* thread = new QThread();
    2. MyObject* object = new MyObject();
    3.  
    4.  
    5. connect(object,SIGNAL(mySignal()),this,SLOT(mySlot())); // synchronous
    6.  
    7. object->moveToThread(thread);
    8.  
    9.  
    10. thread->start();
    To copy to clipboard, switch view to plain text mode 
    Last edited by Qiieha; 13th August 2015 at 15:52.

  2. #2
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: moveToThread and connecting Signals

    What did your testing show?
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  3. #3
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    My testing shows that behaviour, but I don't understand it.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Quote Originally Posted by Qiieha View Post
    I want to figure out the difference between connecting signals of an object before moveToThread and connecting signals after moveToThread method.

    Is it right that first assumption results in asynchron slot calls of mySlot and second results in synchron slot calls of mySlot?
    There is no difference.
    In both cases the connect does not specify a connection type, thus both implicitly use Qt::AutoConnection.
    In both cases the sender and receiver objects live in different threads, so the resulting connection behavior is Qt::QueuedConnection, i.e. asynchronous.
    in both cases you can force synchronous calls by specifying the connection type as Qt:irectConnection

    Cheers,
    _

  5. #5
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: moveToThread and connecting Signals

    anda_skoa, I certainly don't disagree with what you posted, but I wanted to make sure I understand correctly.

    I thought that for signals/slots between different threads, you *must* used Qt::QueuedConnection (or default to Qt::AutoConnection) for the slot to be executed in the receiver thread. This is done asynchronously of course since the event is posted in the receiver's event loop.

    Specifying Qt::DirectConnection may indeed result in the slot being invoked synchronously, but I believe that means that it will execute in the same thread as the sender, which is likely to cause problems if the slot uses member variables or executes other methods in the receiving class.

    Is that correct or is my understanding incorrect?

    Thanks
    Last edited by jefftee; 14th August 2015 at 01:19.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Quote Originally Posted by jefftee View Post
    I thought that for signals/slots between different threads, you *must* used Qt::QueuedConnection (or default to Qt::AutoConnection) for the slot to be executed in the receiver thread. This is done asynchronously of course since the event is posted in the receiver's event loop.
    Exactly.

    Quote Originally Posted by jefftee View Post
    Specifying Qt::DirectConnection may indeed result in the slot being invoked synchronously, but I believe that means that it will execute in the same thread as the sender, which is likely to cause problems if the slot uses member variables or executes other methods in the receiving class.
    Yes, also correct.
    If you force a direct conncetion, then you will need explizit synchronization between threads.

    To summarize:

    - Qt::DirectConnection: like a direct method call. Slot called by the thread that executes "emit"
    - Qt::QueuedConnection: always asynchronous/indirect call. Slot called by thread owning the receiver object.
    - Qt::AutoConnection:
    * if thread that executes "emit" is the receiver object's owner -> behaves like Qt::DirectConnection
    * if thread that executes "emit" is not the receiver object's owner -> behaves like Qt::QueuedConnection

    Qt::AutoConnection does "the right thing" for most use cases, so we only rarely see connect() with an explicit connection type argument.
    But both specific options have their use cases.

    Cheers,
    _

  7. The following user says thank you to anda_skoa for this useful post:

    jefftee (15th August 2015)

  8. #7
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    I'm a bit confused, cause I also agree with that what you are posted, but the results of following test confuse me. Maybe I did something wrong. I know passing a pointer through signal is very bad practice, but
    it's just within the meaning of a test.

    In the attachements there's a small testApp. Maybe you could tell me, what I have to change, so that the app work properly.

    Explanation:
    In main.cpp I start some QRunnables via QThreadPool and wait for finishing.
    In the QRunnable I create an Object and connect a signal to a slot of a singleton and emit the signal. The slot of the singleton should get called synchronously. I tried Qt:irectConnection, etc... Until now I did not achieve the explected result.

    And I don't think I need a QMutex at the slot of the singleton.

    Qt Code:
    1. void NetworkAccessManager::doIt(MyObject* me)//slot of singleton, should get called synchronously
    2. {
    3. //QMutexLocker locker(&mutex);
    4. qDebug() << this->thread()->currentThreadId();
    5. qDebug() << "doIt" << me->getName();
    6. qDebug() << "1";
    7. qDebug() << "2";
    8. qDebug() << "3";
    9. qDebug() << "4";
    10. qDebug() << "5";
    11. me->emitFinished();
    12. }
    To copy to clipboard, switch view to plain text mode 
    Attached Files Attached Files
    Last edited by Qiieha; 14th August 2015 at 09:01.

  9. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Quote Originally Posted by Qiieha View Post
    In the QRunnable I create an Object and connect a signal to a slot of a singleton and emit the signal. The slot of the singleton should get called synchronously.
    And it should.
    Have you checked the thread id at the emit and in the slot?

    Cheers,
    _

  10. #9
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    If it's Qt:irectConnection the ThreadID is (as expected and posted from you) the same. So how can I achieve that the slot is called serialized, if multiple runnables "call" the slot at the same time? QMutex is the solution, right?

    If it's Qt::AutoConnection the slot never get called. Why?
    Last edited by Qiieha; 14th August 2015 at 09:49.

  11. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Quote Originally Posted by Qiieha View Post
    If it's Qt:irectConnection the ThreadID is (as expected and posted from you) the same. So how can I achieve that the slot is called serialized, if multiple runnables "call" the slot at the same time? QMutex is the solution, right?
    yes

    Quote Originally Posted by Qiieha View Post
    If it's Qt::AutoConnection the slot never get called. Why?
    The thread of the receiver object, in your case the main thread, is not running an event loop.
    Qt::QueuedConnection behavior needs an event loop in the receiver thread, to process the "call slot asynchronously" event.

    Cheers,
    _

  12. #11
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Ok thanks for the explanation!

    Can I borrow your know-how from you for follwing assumption:

    Supposed I have class MainObject. Class MainObject has a QThread* as member, which is initial set to 0.
    If the thread is needed while execution it gets created and it's signal destroyed() is connected to a slot setThreadToNULL in MainClass, which set the member-pointer to 0.

    In the destructor of main class the thread pointer is checked if it's a NULL-Pointer. If yes, the thread has completed. If no, the thread has not completed, and has to be terminated in destructor.

    If the connection between them is direct, following could happen:

    Qt Code:
    1. MainObject::~MainObject{
    2.  
    3. if(thread){
    4.  
    5. ....// thread gets destroyed in the meantime
    6.  
    7. //here thread->terminate(); crashes
    8.  
    9. }
    10. }
    To copy to clipboard, switch view to plain text mode 

    How can you achieve that this cannot happen? QPointer?

    thanks
    Last edited by Qiieha; 14th August 2015 at 11:13.

  13. #12
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    You can use either locking with a mutex or use a QAtomicPointer with fetchAndStoreOrdered().

    Also, never call QThread::terminate()

    Cheers,
    _

  14. #13
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Ok, so if I decide to use QMutex, all I have to do is to guard the setThreadToNULL slot and the destructor.

    The mutex will prevent(block) the thread from deleting, while destructor is executing. Right?
    Last edited by Qiieha; 14th August 2015 at 13:29.

  15. #14
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Yes, but I don't really understand why you need to set the variable to null and not just always delete the thread at the end?

    Cheers,
    _

  16. #15
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Cause I think deleting a QThread while executing is dangerous, isn't it?

    If I don't finish the threading properly the app chrashes.

    Qt Code:
    1. if(worker){//thats the pointer that is checked
    2. worker->interrupt();//a custom method that finishes the run method in object Worker, which is moved to QThread
    3. thread->quit();
    4. if(!thread->wait(3000))
    5. {
    6. thread->terminate();
    7. thread->wait();
    8. }
    9.  
    10. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Qiieha; 14th August 2015 at 16:42.

  17. #16
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Quote Originally Posted by Qiieha View Post
    Cause I think deleting a QThread while executing is dangerous, isn't it?
    Yes, but you can always do the same operation:
    - you tell the thread to stop
    - you wait for the thread to stop
    - you delete the thread object

    No need for the thread to "remove itself".

    Cheers,
    _

  18. The following user says thank you to anda_skoa for this useful post:

    Qiieha (17th August 2015)

  19. #17
    Join Date
    Apr 2011
    Posts
    195
    Thanks
    49
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: moveToThread and connecting Signals

    Ok, that's true.
    Thank you for explanations and tips concerning threading behaviour, Connecting-Types, etc.
    Your support is great.

Similar Threads

  1. Connecting signals and slots from different process
    By Momergil in forum Qt Programming
    Replies: 3
    Last Post: 8th February 2014, 15:59
  2. Connecting Qml signals to Qt
    By mots_g in forum Qt Programming
    Replies: 5
    Last Post: 12th May 2011, 11:37
  3. Connecting QML signals with Qt slots
    By KIBSOFT in forum Qt Quick
    Replies: 1
    Last Post: 15th November 2010, 09:18
  4. Connecting signals and slots help pls
    By bod in forum Qt Programming
    Replies: 9
    Last Post: 1st July 2008, 15:01
  5. QHttp signals not connecting...
    By trobbins0000 in forum Newbie
    Replies: 1
    Last Post: 27th February 2007, 02:45

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.