很多时候我们都希望所有阻塞调用控制在一个确定的时间段,而不是一直等待直到就绪。std::condition_variablestd::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;
}