How can I cause a thread to timeout?



  • I have an object derived from QThread. It tries to connect to a URL, but due to a problem with some remote machines, and my RSS feeding library, the attempt will sometimes hang. I need the thread to give up and emit a signal after say 10 seconds. How can I setup my QThread derived object to do this?



  • Set a QTimer for 10000 milliseconds, single-shot and connect its timeout() signal to a slot that calls the QNetworkReply abort() function and tells the rest of the world as required.



  • Yust create QTimer instance and in run():
    @
    void MyThread::run()
    {
    timer.setInterval(10000);
    connect(timer, SIGNAL(timeout()), this, SLOT(whatToDo()));
    }

    void MyThread::whatToDo()
    {
    // some actions
    }
    @



  • I've tried this using the singleShot approach and my slot never gets fired after 5 seconds (5000ms). No errors either that I can see. Nothing happens.



  • [quote author="Little Red Wolf" date="1340815908"]I've tried this using the singleShot approach and my slot never gets fired after 5 seconds (5000ms). No errors either that I can see. Nothing happens.[/quote]

    Can you use it in my way, please?



  • [quote author="tucnak" date="1340816813"][quote author="Little Red Wolf" date="1340815908"]I've tried this using the singleShot approach and my slot never gets fired after 5 seconds (5000ms). No errors either that I can see. Nothing happens.[/quote]

    Can you use it in my way, please?[/quote]

    I just tried your way and it said that timers can not be started from another thread. My timer is a member of the QThread derived class. Right now I'm very confused. Timing out my thread shouldn't be so hard should it?



  • Seems what you need is

    @
    QAbstractSocket::waitForConnected()
    @



  • Unfortunately I'm not using Qt for the network access, I'm using a 3rd party library called feedreaderlib, it reads RSS feeds but some invalid URLs that a user could enter will cause it to hang. I need to be able timeout the thread that I use to run that library on (it also has its own threads btw).



  • OK, then you want to start a timer when your connection started, and kill the connection when the timer timeout?

    QTimer can be used in such cases. QTimer can use create in any thread which runing a Qt EventLoop. And make sure that start/stop is called in the same thread in which the QTimer is created, otherwize, signal and slot should be used, or QMethod::invoke().



  • [quote author="Little Red Wolf" date="1340833668"]I just tried your way and it said that timers can not be started from another thread.[/quote]
    Be aware that members of an object belong to the same thread the object itself lives in, which is the thread it was created (or moved to using QObject::moveToThread()) and which is not the thread the run method is executed in (unless, again, the object has been moved there). So you can't start a member timer in run(), as both belong to seperate threads.

    If the external library provides no means to set a timeout or abort an already issued command you will have to terminate the executing thread - which is usually quite a bad idea, as the thread (and thus the code which is executed in) can be cancelled anywhere in its codepath (possibly before any acquired resources are freed).

    The better option is to continue the workflow in your application if the thread doesn't finish within a certain amount of time and let the thread run out in the background and discard the result once finished.

    An as always when it comes to threads in Qt make sure you've read "Threads, Events and QObjects":http://qt-project.org/wiki/Threads_Events_QObjects, "QThreads - General Usage":http://qt-project.org/wiki/QThreads_general_usage and "You Are Doing It Wrong":http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/.



  • @Lukas:

    Thank you for the links. I'm studying multithreading only to know its possibilities, and those links are just what I needed :-)


Log in to reply
 

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