C++/Qt:如何创建一个可以暂停的繁忙循环?
C++/Qt: How to create a busyloop which you can put on pause?
对于这个问题,有没有比创建一个带有在循环中检查的全局布尔标志的类似自旋锁的结构更好的答案?
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; });
// ...
}
首先,我们在检查标志时浪费了 CPU 时间。其次,我们需要两个单独的按钮才能使该方案起作用。我们如何使用 Qt 的槽信号机制来获得更简单的解决方案?
您可以使用 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));
}
这不会粗暴地检查标志以继续,相反,它会让线程休眠直到收到通知。
您只需让 paused = true;
暂停,让 cv_start_stop.notify_one();
或 cv_start_stop.notify_all();
取消暂停。
对于这个问题,有没有比创建一个带有在循环中检查的全局布尔标志的类似自旋锁的结构更好的答案?
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; });
// ...
}
首先,我们在检查标志时浪费了 CPU 时间。其次,我们需要两个单独的按钮才能使该方案起作用。我们如何使用 Qt 的槽信号机制来获得更简单的解决方案?
您可以使用 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));
}
这不会粗暴地检查标志以继续,相反,它会让线程休眠直到收到通知。
您只需让 paused = true;
暂停,让 cv_start_stop.notify_one();
或 cv_start_stop.notify_all();
取消暂停。