Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Pause and Continue a Thread?



  • This post is deleted!


  • When you start a QThread it will run its own event loop. doStuff is the first slot that is executed in that event loop. However, by your design, the while-loop will block the event loop of this thread. The stop signal will thus never be executed as stop will be executed in the context of the receiver, i.e. the event loop of that other thread and not the main event loop.

    Here are a few ideas how you could solve your problem:

    1. Have the stop_action connect to a slot in MainWindow that directly calls self.worker.stop(). This will be executed in the main event loop, so blocking in the other thread is not a problem. Someone might mention that Worker.stopped is not an atomic variable. As long as you don't want to have an immediate reaction this will not be a problem. The worker thread will pick up the change eventually. (Actually, you might even not notice any delay.)
    2. If you want to simulate an infinite loop inside the event loop of that thread, you can have a QTimer running with a timeout of 0s. This will constantly put a call to the same slot into your event loop. Still, the stop signal has a chance to slip in between and you'll have a chance to kill that timer.
    3. As you said before you want to send data to the worker thread through a signal-slot connection. This approach would be the preferred way. Only do work in the worker thread when you have new data. Just call a slot in the worker thread (through a signal) with the new data and do the work. Afterwards the worker thread can idle to wait for new data. No need to have a loop running.

  • Lifetime Qt Champion

    Hi,

    Can you show the code you are using to setup doStuff and stop ?



  • This post is deleted!

  • Lifetime Qt Champion

    @Thomas-Stein How did you connect button signal to stop() method? I think you need to use direct connection in this case as your worker thread does not have running/non blocked event loop.



  • This post is deleted!


  • This post is deleted!

  • Qt Champions 2017

    Acquire an empty semaphore to pause, and release it to unpause. Use a direct connection to the resume slot when you do. I don't do python, but you could easily transform the following c++ snippet I hope:

    class Worker : public QObject
    {
    public slots:
        void pause();
        void resume();
    
    private:
        QSemaphore semaphore;
    };
    
    void Worker::pause() //< Qt::AutoConnection to pause in the worker thread
    {
        semaphore.acquire();
    }
    
    void Worker::resume()
    {
        semaphore.release() //< Qt::DirectConnection to resume
    }
    

    Matching pause -> resume pairs are required for this to run correctly (i.e. to have the next pause actually pause).

    EDIT: Disregard the above, has nothing to do with the problem as I've not read the whole original post

    If you're going to block the event loop there's no reason to actually use the worker object. If you want an endless loop, use a QTimer with 0 interval, and stop it whenever you want to pause.



  • When you start a QThread it will run its own event loop. doStuff is the first slot that is executed in that event loop. However, by your design, the while-loop will block the event loop of this thread. The stop signal will thus never be executed as stop will be executed in the context of the receiver, i.e. the event loop of that other thread and not the main event loop.

    Here are a few ideas how you could solve your problem:

    1. Have the stop_action connect to a slot in MainWindow that directly calls self.worker.stop(). This will be executed in the main event loop, so blocking in the other thread is not a problem. Someone might mention that Worker.stopped is not an atomic variable. As long as you don't want to have an immediate reaction this will not be a problem. The worker thread will pick up the change eventually. (Actually, you might even not notice any delay.)
    2. If you want to simulate an infinite loop inside the event loop of that thread, you can have a QTimer running with a timeout of 0s. This will constantly put a call to the same slot into your event loop. Still, the stop signal has a chance to slip in between and you'll have a chance to kill that timer.
    3. As you said before you want to send data to the worker thread through a signal-slot connection. This approach would be the preferred way. Only do work in the worker thread when you have new data. Just call a slot in the worker thread (through a signal) with the new data and do the work. Afterwards the worker thread can idle to wait for new data. No need to have a loop running.

Log in to reply