很多时候我们都希望所有阻塞调用控制在一个确定的时间段,而不是一直等待直到就绪。std::condition_variable
和std::future
都提供了成员函数wait_for()
和wait_until()
,每个都有两个重载版本,用于执行有时间限制的等待,前者处理基于时间段的超时,后者处理时间点的超时。C++11引入了<chrono>
头文件,定义了时间相关的应用,可以结合这两个函数使用。std::chrono::duration<>
可以处理时间段,std::chrono::time_point<>
则处理时间点。
#include <iostream>
#include <chrono>
#include <future>
#include <Windows.h>
int task()
{
Sleep(30);
return 2333;
}
int main()
{
std::future<int> f = std::async(task);
if (f.wait_for(std::chrono::milliseconds(30)) == std::future_status::ready)
{
std::cout << "Task done!\n";
}
else
{
std::cout << "Task time out!\n";
}
return 0;
}
在task()
中休眠30毫秒,导致task()
执行之间大于设置的等待时间,30毫秒后future
仍未就绪,任务超时。也可以在future
上等待到一个时间点,如等到到现在之后的30毫秒后:
f.wait_until(std::chrono::steady_clock::now() + std::chrono::milliseconds(30)) == std::future_status::ready
条件变量的等待方式类似,可以在一个条件变量对象上调用wait_for()
或wait_until()
,判断返回值是否是std::cv_status::timeout
,如下:
std::condition_variable cv;
std::mutex m;
bool done;
some_task()
{
std::chrono::timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(500);
std::unique_lock<std::mutex> lk(m);
while(!done)
{
if(cv.wait_until(lk, timeout) == std::cv_status::timeout)
break;
}
return done;
}
最后一次更新于2022-09-04
0 条评论