Discussion about threads, moveToThread etc.



  • [quote author="peppe" date="1311661270"]Well, do you know of a better API you can use instead of Sleep()? You could patch QThread::sleep () and submit a MR :)[/quote]

    if you want to let the GUI to keep doing its while it waits then call QCoreApplication::processEvents()

    if you really need to sleep because you have other code you want to run then just do it in a qthread and call moveToThread. I have done it and it works very well.

    EDIT: split of of this thred: "Poor QThread::sleep() and ::usleep() resolution on Windows":http://developer.qt.nokia.com/forums/viewthread/8098/P15 , Gerolf



  • [quote author="yan bellavance" date="1311786693"]
    if you want to let the GUI to keep doing its while it waits then call QCoreApplication::processEvents()
    [/quote]
    Doing this, no problem, all fine. Though processEvents() is some sort of "the opposite" of sleep(), I still call it during my display loop to keep the GUI responsive.

    [quote author="yan bellavance" date="1311786693"]
    if you really need to sleep because you have other code you want to run then just do it in a qthread and call moveToThread. I have done it and it works very well.[/quote]
    Doing this. But tell me: I've got a worker thread doing stuff. It waits for hardware. It needs to poll. I would like to sleep between polling, but not for 15ms, more like 0.1ms (so I don't miss when my hardware is ready). How would I do this?



  • Well one thing I might have forgotten to mention is that I don't call exec in that QThread so It actually does not have an eventloop because I have implemented a polling technique. Just put a forever loop in your run function and call QThread::sleep ::msleep ::usleep from there. here is a small example:

    @//the timeout periods are multiples of the delay period for consistency. I dont
    //need that much accuracy but if I did I woull read a timer and do the delta
    //time of each loop
    void myQthread::run()
    {
    //do init stuff here. you could call moveTothread either in constructor of
    //qthread or at the end of you init in the run function but before the forever loop.

    forever{
        this->msleep(delay);
        doLogsTimeout-=delay;
        clockUpdTimeout-=delay;
        tduRefreshTimeout-=delay;
        
        if(doLogsTimeout<=0){
            doLogsTimeout = LOGS_TIMEOUT_PERIOD;
            //....do what you need to do here
        }
        if(clockUpdTimeout<=0){
            clockUpdTimeout = CLOCKUPD_TIMEOUT_PERIOD;
            //....do what you need to do here
        }
        if(tduRefreshTimeout<=0){
            tduRefreshTimeout = TDUREFRESH_TIMEOUT_PERIOD;
            //....do what you need to do here
        }
    }
    

    }

    @



  • [quote author="yan bellavance" date="1311788442"]Well one thing I might have forgotten to mention is that I don't call exec in that QThread so It actually does not have an eventloop because I have implemented a polling technique. Just put a forever loop in your run function and call QThread::sleep ::msleep ::usleep from there. [/quote]

    If you have read the thread completly, this is what he wants to do and what (on windows) has the 15 mSec resolution. This is not due to Qt it's due to windows. And he want's to do not busy waiting, so sleep would be great but has the resolution problem on WINDOWS.



  • [quote author="Gerolf" date="1311793338"]
    If you have read the thread completly, this is what he wants to do and what (on windows) has the 15 mSec resolution. This is not due to Qt it's due to windows. And he want's to do not busy waiting, so sleep would be great but has the resolution problem on WINDOWS.

    [/quote]

    I wrote that because i was referring to:

    [quote author="peppe" date="1311757068"]
    I still think that using sleep() in any code is usually wrong
    [/quote]

    And also referring to other thread that discourage the use of sleep. I want to make evident that if moveToThread is not called then calling sleep from the QThread is actually done from the main thread and can make the GUI freeze. So I am not fixing the delay resolution issue but am trying to help him make things safer. Also I was hoping this would at least give him more constance in the sleep resolution.



  • If you don't use moveToThread, you can also call sleep inside a worker thread, that has no influence in general. Inside QThread::run you can call sleep and it will be inside the worker thread.

    Call sleep in the main thread might have som unexpected result to some users as the UI freezes and mostly it is said: don't call sleep in main thread.



  • if you dont moveToThread then the worker thread and GUI thread share the same event loop and that can cause problems. For example: calling QUdpSocket polling functions such as waitForReadyRead() and waitForBytesWritten()



  • that depends where you call them. and a thread only has an event loop, if you run it. If you implement everything inside the thread's run method, and do "normal" stuff there, all works. I do that all the time, without an event loop and without moveToThread. It just depends, where you create the object. If you create them inside run, all is fine. The currently active thread during object creation is the needed information. So create the QUdpSocket inside run, it works.

    EDIT: if you create the objects inside the QThread's constructor, the are attached to the creating thread, not the QTHread object



  • [quote author="yan bellavance" date="1311786486"]You have to be carefull when people tell you not to call a function because it's "dangerous". If we listen to them then we cannot call: QCoreApplication::processEvents(), QThread::sleep(), QObject::moveToThread() or others I have not read of. They say this because of the context in which they are programming, they have guidelines that limit what they can do.[/quote]

    This thread has NOTHING to do with those methods. And nobody said that it's dangerous. Only that they lead to bad/fragile code.

    [quote]
    Of course you should never call sleep() in the GUI main thread (if you don't moveToThread() your QThread then it's still in the main thread and then I would see why calling sleep should be avoided) and if you call processEvents(), do it from the GUI main thread preferably.
    [/quote]

    ... you CAN'T call QThread::sleep from the main thread, since you don't have access to that QThread protected sleep() ...

    [quote]
    I built a qt app on Linux that uses all of these and it's been running for a year now without ever crashing. Also, my app often show its CPU usage as 0% in the system monitor (on windows this would be windows task manager),its very efficient. I do have an i7 intel cpu.
    [/quote]

    And we're talking about Windows.

    [quote author="yan bellavance" date="1311786693"]
    [quote author="peppe" date="1311661270"]Well, do you know of a better API you can use instead of Sleep()? You could patch QThread::sleep () and submit a MR :)[/quote]

    if you want to let the GUI to keep doing its while it waits then call QCoreApplication::processEvents()

    if you really need to sleep because you have other code you want to run then just do it in a qthread and call moveToThread. I have done it and it works very well.[/quote]

    This reply is nonsense -- I was talking about QThread::sleep resolution on Windows. That is, the OP's issue.



  • [quote author="Gerolf" date="1311797834"]that depends where you call them. and a thread only has an event loop, if you run it. If you implement everything inside the thread's run method, and do "normal" stuff there, all works. I do that all the time, without an event loop and without moveToThread. It just depends, where you create the object. If you create them inside run, all is fine. The currently active thread during object creation is the needed information. So create the QUdpSocket inside run, it works.

    EDIT: if you create the objects inside the QThread's constructor, the are attached to the creating thread, not the QTHread object[/quote]

    if you call moveToThread and dont run exec() you do not have an event loop therefore if you have a something like a qtimer in your qthread it won't emit signals and you wont be able to trigger slots connected its signals. There actually used to be a warning about not calling waitForReadyRead and waitForBytesWritten from the main thread as it could make the app crash. I have tried it even inside a qthread and seen this happen and once i used moveToThread, it went away.



  • [quote author="yan bellavance" date="1311799380"]
    if you call moveToThread and dont run exec() you do not have an event loop therefore if you have a something like a qtimer in your qthread it won't emit signals and you wont be able to trigger slots connected its signals. There actually used to be a warning about not calling waitForReadyRead and waitForBytesWritten from the main thread as it could make the app crash. I have tried it even inside a qthread and seen this happen and once i used moveToThread, it went away.[/quote]

    And where did you create the object? I assume in the QThread's constructor. I did not say that signal/slot work without event loop, but it totally works without moveToThread if you create the objects correctly.

    "see peppes wiki article":http://developer.qt.nokia.com/wiki/Threads_Events_QObjects



  • just tried it and it ain't working. Got a bunch of these messages:

    bq. Warning: QObject: Cannot create children for a parent that is in a different thread.

    Of course I can emit signals form the qthread and connect them to slots in the main thread but what you speak of requires the opposite. Anyway I think I just spammed this thread. Sorry about that but it was a discussion in which I learned something from everyone.



  • The cause of that is simple. Objects created in thread B can not have an object in thread A as their parent. So, the first object that you create in the run() method of your QThread, can not have any parent, as there is no QObject available in the same thread that can be used for that. Any following object can get the first object as parent, if that makes sense in your case.

    So: you have to make sure you delete the created object yourself at an appropriate time.



  • [quote author="Andre" date="1311866425"]So: you have to make sure you delete the created object yourself at an appropriate time.[/quote]

    The easiest way to achieve this is to create the first object as object on the stack, and put all other as children of it, Then everything will be deleted correctly :-)



  • Can we please split this thread? It definitely went offtopic.



  • /agree. Is there a way to split a thread? guess so :)



  • done the split



  • bq. Warning: QObject: Cannot create children for a parent that is in a different thread.

      I don't know what I did yesterday trigger that message , i was trying a couple of things but I put the code back to what it was.  I think it is unrelated and I have a pretty good idea where it happened.  
    
      I then took a look at my run function and I did find 1 object created there who's parent is the QThread (first and only one).  What I don't understand is: aren't they the same thread?  The parent of the object declared in run is QThread and moveToThread has been called previously to entering run.   I removed the parent but I still can't trigger slots in the qthread without an event loop. 


  • I think you can boil it all down to this: Where is your object created? If it's in "QThread::run()", then it got it's own concurrent OS-based thread. If not, then it's all in Qt's main GUI thread.

    Even if you create a QThread object, its signals and slots basically "live" in the main thread (as in: the thread where you created the QThread).

    QThread is not so much a real OS-thread, but more like "A wrapper / container which provides a method run, which will be executed in its own thread".

    So you either go the "low level road", re-implement run(), preferrably don't call exec(), and do your processing. Data exchange will have to be protected (by mutexes, semaphores, etc.).

    Or, you could leave run()'s default implementation (which calls exec()). Then you call, from your main (GUI) thread, .moveToThread() on some objects. Specifically: On those objects, whose events (slots) you want to have processed by another OS thread.

    So if you have an QObject MyWorker, and a slot "doWork()", and then you do:
    @
    MyWorker someWorker;
    // now connect some signal to SLOT("doWork()") of someWorker
    QThread workingThread;
    someWorker.moveToThread(workingThread);
    workingThread.start();
    @
    Then this means, whenever the doWork() slot is called, it will be executed in the context of it's own OS thread (the workingThread's thread).

    I personally wouldn't mix those two. EITHER don't subclass QThread at all, don't touch its constructor etc. Do everything signal-slot based, and with .moveToThread().

    OR, you do implement QThread and run(), but you don't call exec() and don't do .moveToThread with this specific class. Edit: or, if you have to, call exec() from this current QThread::run() context, but don't do moveToThread on other objects.

    Just my 2 cents :-)



  • Without an event loop, queued connectiosn won't work inside the thread. The QTHread itself is assigned to the creating thead of the object, it justs hosts the thread.



  • Ok, that's much more precise, thanks :-)



  • [quote author="LinusA" date="1311880952"]I think you can boil it all down to this: Where is your object created? If it's in "QThread::run()", then it got it's own concurrent OS-based thread. If not, then it's all in Qt's main GUI thread.
    Even if you create a QThread object, its signals and slots basically "live" in the main thread (as in: the thread where you created the QThread).
    [/quote]

    What you are saying is true ONLY if you do not call moveToThread.

    If you don't call moveToThread on QThread then both the main thread and QThread will have the same address, if you do call moveToThread then QThread has the same address as objects created inside the run function. I just did the test I can confirm this.

    if you want to test it out just put this in the run function:

    @
    QUdpSocket * FcpSocket; // I declared this pointer in the class but the new is in run so it doesn't matter
    this->FcpSocket=new QUdpSocket(this);
    QThread* sockThread=FcpSocket->thread();
    QThread* fpsEngineThread=this->thread();
    @
    and before this either call moveToThread or not and see the difference, with and without the call to moveToThread.

    Also, I called moveToThread and I do not call exec inside run on purpose, that is how I needed it to be.
    That is why you should call moveToThread when using functions that should not be called from the mainthread.

      P.S. I am on linux platform
    


  • Gerolf, from my previous post you can see that in deed, if you do not call moveToThread, then you should never use this as parent to objects created in run, if you do then both the object parent and QThread will have same address.



  • [quote author="yan bellavance" date="1311978655"]Gerolf, from my previous post you can see that in deed, if you do not call moveToThread, then you should never use this as parent to objects created in run, if you do then both the object parent and QThread will have same address.[/quote]

    Not the same adress, the same thread affinity :-)
    If you do not use signal/slot inside a thread, you need no mopveToThread to access QObejsct inside other threads as their attached one. moveToThread is only needed for signal&slot; stuff and auto connections or to find the correct event loop for a queued slot or function.

    By the way, moveToThread is not a method inside QThread, it's inside QObject sao it can be called in any QObject. But why do you need the QThread to be assigned to it's own hosted thread? A better sollution (from my POV) is to give the thread slots and signals. The users of the thread can connect to the slots, which itself emit a signal that is attached inmsidethe run method with objects that live inside run. Then each object has the correctr thread affinity and it works.



  • I am doing this to separate the QThread from the main thread because I am using:
    @bool QIODevice::waitForBytesWritten ( int msecs )
    bool QIODevice::waitForReadyRead ( int msecs )
    @

    These functions should not be used in a QThread that has the same thread affinity as the main thread. Notice the warning about these functions:

    bq. Warning: Calling this function from the main (GUI) thread might cause your user interface to freeze.

    I have seen other things happen as well: it can create dereferencing errors, somehow qt gets confused and tries for example to delete memory that has a dereferencing count of 0 which causes an exception. By changing the thread affinity of my QThread, I take its memory out of the main thread which eliminated this problem.

    So basically I have done this to protect data.



  • This warning is related to the "physical" thread, not the QThread object. Running it in a worker thread MUST be save, event if you don't call moveToThread on the Thread. But only, if the QIODevice has not the QThread object as parent.



  • [quote author="yan bellavance" date="1312215886"]I am doing this to separate the QThread from the main thread because I am using:
    @bool QIODevice::waitForBytesWritten ( int msecs )
    bool QIODevice::waitForReadyRead ( int msecs )
    @
    [/quote]
    As I understand it, in this case it would be better to use the signals "bytesWritten" and "readyRead". See http://developer.qt.nokia.com/wiki/Threads_Events_QObjects#2b40afeff6025af55f25a6c7ea5ab3bc



  • well it is not safe. And I know this from experience. I had spent a lot of time on this a while back when I was developing that part and I can assure you that it was causing problems. The code without moveToThread would crash once in a while (though it was a rare occurrence it was still unacceptable). The code with moveToThread never crashed. I refer you to the documentation once more:

    bq.
    This function can operate without an event loop. It is useful when writing non-GUI applications and when performing I/O operations in a non-GUI thread.

    Now if it is not safe but is supposed to then there is a Qt bug that needs to be resolved. I reported it but nothing was ever done about it so I took the QThread out of there.



  • [quote author="LinusA" date="1312218342"]
    As I understand it, in this case it would be better to use the signals "bytesWritten" and "readyRead".[/quote]

    Not when a polling technique is used, which is my case. There is no reason why I should not be allowed to do this otherwise, might as well take those functions out of the Qt. If you look at the Blocking Fortune Client example from Qt you will see that this is how they implemented it.



  • Sorry friend but I am not clear where we should overwrite the run() and moveToThread()....so please clear it first.
    Thanx in advance.


  • Moderators

    Hi Ak@sh, see http://qt-project.org/doc/qt-5.1/qtcore/qthread.html

    By the way, this thread is 2 years old. It's best to start a new thread next time.



  • I knew these tow ways but I realy confused when and where I should used which way(overwrite the run() or moveToThread()).

    I request you to reply on this.

    Thanx in advance.....



  • Hi JKSH,
    Tnq very much for your reply.
    I knew these tow ways but I realy confused when and where I should used which way(overwrite the run() or moveToThread()).

    I request you to reply on this.

    Thanx in advance.....



  • Hi Ak@sh,

    you can find answer of your question in the documentation.

    http://qt-project.org/doc/qt-5.1/qtcore/thread-basics.html


  • Moderators

    [quote author="Ak@sh" date="1374741806"]Hi JKSH,
    Tnq very much for your reply.
    I knew these tow ways but I realy confused when and where I should used which way(overwrite the run() or moveToThread()).[/quote]Hi Ak@sh, you're welcome.

    In general, I would:

    • Use moveToThread() if I want two-way communication with the thread using signals+slots or events.
    • Reimplement run() if my thread is very simple, and I don't need to send signals/events to the thread..

    If you tell us what you plan to do with your threads, we can give you better advice.



  • Hi JKSH,

    thanx for your reply.

    In my current projct I already used overwrite the run() method for thread.But I confused when I saw moveToThread() Beacuse,
    Some experts says overwrite the run() is not a proper way to thread.

    please once see this link:-
    http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

    I request you to reply on this.

    Thanx in advanceā€¦..



  • Hi, the blog goes from one extreme to the other.

    In fact, both are right usages. The documentation will be useful for you http://qt-project.org/doc/qt-5.1/qtcore/thread-basics.html


    BTW, if you are interested in the topic, you can have a look at

    http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html



  • Nice Documenaion and han for that.
    They mention this two points -
    If you do not really need an _ -event loop-_ in the thread, you should subclass.
    If you need an -event loop- and handle signals and slots within the thread, you may not need to subclass.

    What they exactly mean with EVENT LOOP ???
    I know might this is very silly que for you but please....


  • Moderators

    An event loop is an infinite loop that processes signals and events. It waits for signals/events to arrive, then it calls functions to handle them.

    The main thread starts an event loop by calling QCoreApplication::exec():
    @
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    // ...

    // This line starts an (infinite) event loop, then
    // returns its status when the loop is exited
    return a.exec&#40;&#41;;
    

    }
    @

    QThread starts an event loop by calling QThread::exec():
    @
    void QThread::run()
    {
    // This line starts an (infinite) event loop, but
    // doesn't return an exit status value
    this->exec();
    }
    @

    Also, see "this page":http://qt-project.org/doc/qt-5.1/qtcore/threads-qobject.html



  • Hii..gm.
    Thnx for ur important time and reply on my query.
    I am not relates the things.
    come again on our main point and please comfirm me that then when we you should subclass QThread class for thread then there is no EVENT LOOP?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.