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.