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

How to process events during infinite loop in Worker thread



  • I've created a Worker object in Qt to process video input indefinitely, and then move it into a QThread to keep the UI thread going. The problem is, I designed it such that the video capture function runs in an infinite loop until interrupted by a flag, and the flag was supposed to be set by a slot in the Worker object, but since the Worker object is inside the infinite loop, it never processes this "quit" slot (or at least I think that's what's happening). I depend on an external library so substituting the video polling for another method is not really an option. Can someone please confirm that this is indeed the problem and suggest a solution? Here's the code:

    class worker : public QObject{
        Q_OBJECT
    public:
        worker(QObject* parent = NULL);
        ~worker(){}
        Q_SLOT void process();
        Q_SLOT void stop();
    private:
        bool quit;
    };
    
    worker::worker(QObject *parent) : QObject(parent){
        quit = false;
    }
    void worker::process(){
        while(!quit){
            //this library call puts the thread to sleep until a frame is available
            WaitForVideoFrame();
        }
    }
    void worker::stop(){
        quit = true;
    }
    

    and then from the UI object I have:

    MyWorker = new worker();
    QThread* thread = new QThread;
    MyWorker->moveToThread(thread);
    connect(thread, SIGNAL(started()), MyWorker, SLOT(process()));
    QPushButton* stop_button = new QPushButton(this);
    connect(stop_button, SIGNAL(clicked(bool)), MyWorker, SLOT(stop()));
    thread->start();
    

    The problem here is that when I press the stop_button, nothing happens, the worker keeps running the loop. Is there maybe a function that I can call to yield processing time to the event loop from within the infinite loop? Or a better design/solution for this? Any suggestions are welcome.


  • Moderators

    @armandomartins said in How to process events during infinite loop in Worker thread:

    since the Worker object is inside the infinite loop, it never processes this "quit" slot (or at least I think that's what's happening).

    Yes, that's exactly what's happening. Event loops (which process signals/slots) and infinite loops are incompatible with each other; you cannot have both in the same thread.

    I depend on an external library so substituting the video polling for another method is not really an option. Can someone please confirm that this is indeed the problem and suggest a solution?

    In this case:

    1. Don't use a worker QObject + moveToThread(). Instead, subclass QThread and put your infinite loop inside your override of QThread::run().
    2. From the main thread, call QThread::requestInterruption() when you want to quit. (You don't need to implement your own Quit function)
    3. Replace while (!quit) {...} with while (!isInterruptionRequested()) {...}

    This should also significantly simplify your code.

    See:


Log in to reply