Home > front end >  C /Qt: How to create a busyloop which you can put on pause?
C /Qt: How to create a busyloop which you can put on pause?

Time:12-16

Is there a better answer to this question than creating a spinlock-like structure with a global boolean flag which is checked in the loop?

bool isRunning = true;

void busyLoop()
{
    for (;;) {
        if (!isRunning)
            continue;
        // ...
    }
}

int main()
{
    // ...
    QPushButton *startBusyLoopBtn = new QPushButton("start busy loop");
    QObject::connect(startBusyLoopBtn, QPushButton::clicked, [](){ busyLoop(); });
    
    QPushButton *startPauseBtn = new QPushButton("start/pause");
    QObject::connect(startPauseBtn, QPushButton::clicked, [](){ isRunning = !isRunning; });
    // ...
}

To begin with, we waste the CPU time while checking the flag. Secondly, we need two separate buttons for this scheme to work. How can we use Qt's slot-signal mechanism for a simpler solution?

CodePudding user response:

You can use std::condition_variable:

    std::mutex mtx;
    std::condition_variable cv_start_stop;

    std::thread thr([&](){
        /**
         * this thread will notify and unpause the main loop 3 seconds later
         */
        std::this_thread::sleep_for(std::chrono::milliseconds(3000));
        cv_start_stop.notify_all();
    });

    bool paused = true;
    while (true)
    {
        if (paused)
        {
            std::unique_lock<std::mutex> lock(mtx);
            cv_start_stop.wait(lock); // this will lock the thread until notified.
            std::cout << "thread unpaused\n";
            paused = false;
        }
        std::cout << "loop goes on until paused\n";
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

This will not brutally check for a flag to continue, instead, it will put thread to sleep until notified.

You will simply make paused = true; to pause and cv_start_stop.notify_one(); or cv_start_stop.notify_all(); to unpause.

  •  Tags:  
  • c qt
  • Related