Results 1 to 3 of 3

Thread: [thread]how to suspend a work thread

  1. #1
    Join Date
    Jul 2008
    Qt products

    Default [thread]how to suspend a work thread

    I want to suspend a work thread, so i tried to call wait(ms). But it never worked.
    When I called wait() in the MsgThread derived from QThread, it entered into Line02/03, then returned from wait(). When I called wait(ms) in some function of a class derived from QDialog, then it reached Line 10, and then just jumped to Line22 after ms; however, the working thread did not been suspended. So wait() did not suspend the desired thread, it worked to the GUI thread!

    So what can I do to get the work thread to be suspended?
    thanks a lot!
    By the way, the program has only one workthread

    Qt Code:
    1. Q_D(QThread);
    2. QMutexLocker locker(&d->mutex);
    4. if (d->id == GetCurrentThreadId()) {
    5. qWarning("QThread::wait: Thread tried to wait on itself");
    6. return false;
    7. }
    8. if (d->finished || !d->running)
    9. return true;
    11. ++d->waiters;
    12. locker.mutex()->unlock();
    14. bool ret = false;
    15. switch (WaitForSingleObject(d->handle, time)) {
    16. case WAIT_OBJECT_0:
    17. ret = true;
    18. break;
    19. case WAIT_FAILED:
    20. qErrnoWarning("QThread::wait: Thread wait failure");
    21. break;
    22. case WAIT_ABANDONED:
    23. case WAIT_TIMEOUT:
    24. default:
    25. break;
    26. }
    28. locker.mutex()->lock();
    29. --d->waiters;
    To copy to clipboard, switch view to plain text mode 
    Last edited by jpn; 27th July 2008 at 09:47. Reason: missing [code] tags

  2. #2
    Join Date
    Jan 2006
    Warsaw, Poland
    Thanked 975 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Unix/X11 Windows

    Default Re: [thread]how to suspend a work thread

    Don't wait, sleep!

  3. #3
    Join Date
    Apr 2013
    Qt products

    Default Re: [thread]how to suspend a work thread

    To suspend a working thread I used the following approach.

    Here is a part of my GUI.h file:

    QAtomicInt check; //it has to be public to be reachable from a
    //working thread; we’ll use it as a pause flag
    int receiver; //internal flag
    QThread *thread; //we will use thread, won’t we?
    Worker *worker; //here is where all the work is done
    void begin(); //we will also need a signal

    Here is a part of my GUI.cpp file:

    receiver = 0;
    check = QAtomicInt(1); //you may use any number, even 42
    pb = new QPushButton("Start"); //I used a button to start, suspend and resume a working thread
    connect(pb, SIGNAL(clicked()), this, SLOT(start()));
    thread = new QThread; //who did not read Maya Posch’s blog?
    worker = new Worker(this); //we need a pointer to this to reach
    //our check flag, remember?
    connect(this, SIGNAL(begin()), worker, SLOT(compute()));
    connect(worker, SIGNAL(over()), this, SLOT(ovr()));

    void Widget::start()
    if ( receiver == 0 ) { //just to remember where we are
    receiver = 1;
    emit begin(); //here we start our heavy job
    } else if ( receiver == 1 ) { //here we pause it
    receiver = 2;
    while ( !(check.testAndSetOrdered(2, 3))) {} //this is where all the magic is done testAndSetOrdered may fail
    //so we repeat it until it succeeds
    } else {
    receiver = 1;
    while ( !(check.testAndSetOrdered(3, 1))) {} //first we have to restore check to its normal value. This time
    //we can almost never fail, but just in case I leave the while block here

    emit begin(); //here we resume our job

    Here is my worker.h file:

    class Worker : public QObject { //do not ask why I did not inherit from QThread, just read Maya Posch
    public slots:
    void compute(); //the only slot here that does it all
    void over(); //we have to inform the GUI thread
    //that we are over
    int limit, counter; //it is important to declare counter
    Widget *parent;

    Here is a part of my worker.cpp file:

    Worker::Worker(Widget* par)
    parent = par; //store a pointer to the GUI thread
    counter = 1; //it is important to initialize counter HERE
    limit = 100000000;

    void Worker::compute()
    while ( counter < limit ) {
    if ( parent->check.testAndSetOrdered(1, 2) ) { //THERE

    //testAndSetOrdered may fail, if check was set to another value in the GUI thread.
    //If this is the case, we return and DO NOTHING. Compared to techniques with wait()
    and QMutex and QWaitCondition, this approach is easier on CPU.

    //do your calculations HERE

    counter += 1;
    parent->check.testAndSetOrdered(2, 1); //before the next iteration we have to restore
    //check to 1, and we don’t care if we fail here

    } else {

    //now we get ready for yet another round of calculations and inform the GUI
    //thread that we are over with this round.

    counter = 1;
    emit over();

    The basic idea is to use QAtomicInt special features. In the worker thread we check if CHECK is unchanged.
    If it was changed we return and do nothing. To change it we have to compete with the worker thread for
    access to CHECK from the GUI thread. That is why we need while block. We put while block in the resume
    section, though in most cases it will succeed with the first attempt. But we are dealing with multi-threading,

Similar Threads

  1. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 07:13
  2. Replies: 10
    Last Post: 20th March 2007, 23:19
  3. Problem closing a QMainWindow in Qt4.2
    By ian in forum Qt Programming
    Replies: 11
    Last Post: 17th October 2006, 01:49

Tags for this Thread


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.