当我们执行一个如图片处理视频处理等费时费CPU的操作时,很多时候是将其移到一个线程,并监测其进度,如果这个时候我们需要提供 暂停、恢复、停止的功能,本文就用C++11来实现其功能。
C++11 提供了线程(std::thead,std::async等)以及线程安全等控制(如std::unique_lock std::lock_guard, std::condition_variable等),我们目前假定执行一个任务:任务的粒度是当前线程睡眠1秒,并输出当前进度。我们将任务执行实现在TestThread中的void runProcess(),并在该类提供 暂停(void pause())、恢复(void resume())、停止(void stop())的功能。
暂停和停止的功能主要是通过条件变量std::condition_variable和互斥变量std::mutex来实现
- 在每一次循环中检查std::condition_variable::wait是否阻塞。第二个参数则是当返回true才不会阻塞当前线程
void TestThread::runProcess()
{
std::thread testThread(
[&]{
for(int i = 0; i < 100; i++)
{
if(!m_isStop)
{
std::cout << "current process progress: " << i << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, [this]{return !m_isPause;});
}else{
break;
}
}
});
testThread.detach();
}
- 当需要暂停时,我们将m_isPause设置为true,再通过std::condition_variable::notify_one通知mutex,从而阻塞当前线程同理,要解除阻塞的线程,则将m_isPause设置为false,再通知mutex,停止则比较好理解,即退出线程,这里需要说一下,线程的退出一般是通过线程的自然死亡来退出线程,即设立标志位(m_isStop)
void TestThread::pause()
{
std::unique_lock<decltype(m_mutex)> l(m_mutex);
m_isPause = true;
m_cv.notify_one();
}
void TestThread::resume()
{
std::unique_lock<decltype(m_mutex)> l(m_mutex);
m_isPause = false;
m_cv.notify_one();
}
void TestThread::stop()
{
m_isStop = true;
}
调用main函数如下
int main()
{
TestThread testThread;
testThread.runProcess();
int c;
while ((c = getchar()) != 'q')
{
switch(c)
{
case 'p':
testThread.pause();
break;
case 'r':
testThread.resume();
break;
case 's':
testThread.stop();
break;
}
}
}