多线程的程序执行时阻塞可以是某条件达成,也可以是限时等待。
比如延时超时,等待某个时长后程序进行下一个语句,或者绝对超时,在某个时间点进行下一步执行语句。
我们先从时钟类开始介绍。
C++的时钟类定义在头文件 <chrono> 中,描述时间的信息有:当前时刻 now(),返回 time_point,计时时刻长度 ratio,持续时间,是否是恒稳时钟。
计时单元 ratio 的表示方式为秒的分数,比如 std::ratio<1, 1000> 就是一千分之一秒,即毫秒。std::ratio<60, 1>是60秒,即一分钟。
持续时间 duration 的表示方式为std::chrono::duration<计时的整数类型, 计时单元>,如下所示:
using namespace std::chrono_literals; // 需要C++ 14
std::chrono::duration<long, std::ratio<3600, 1>> oneDay = 24h;
// auto oneDay = 24h;
std::chrono::duration<long, std::ratio<60, 1>> halfAnHour = 30min;
// auto halfAnHour = 30min;
std::chrono::duration<long long, std::ratio<1, 1000>>
microSecond = 30ms;
// auto microSecond = 30ms;
std::chrono::duration<short, std::ratio<60, 1>> durations(100);
可通过 auto 和 计时单位 h, min 等进行简化(需支持C++14标准)。
当前时刻的描述比较复杂,std::chrono::time_point<是否恒稳,最短持续时长>,如下:
std::chrono::time_point<
std::chrono::system_clock,
std::chrono::duration<long long, std::ratio<1, 1000000000>>>
systemTimeNow = std::chrono::system_clock::now();
// auto systemTimeNow = std::chrono::system_clock::now();
std::chrono::time_point<
std::chrono::steady_clock,
std::chrono::duration<long long, std::ratio<1, 1000000000>>>
steadyTimeNow = std::chrono::steady_clock::now();
// auto steadyTimeNow = std::chrono::steady_clock::now();
std::chrono::time_point<
std::chrono::steady_clock,
std::chrono::duration<long long, std::ratio<1, 1000000000>>>
highResolutionTimeNow = std::chrono::high_resolution_clock::now();
// auto highResolutionTimeNow = std::chrono::high_resolution_clock::now();
当前时刻可以是系统时钟,恒稳时钟,最高精度时钟(不一定有独立定义)。
我们可以在线程函数中进行等待 std::this_thread::sleep_for(),同时在 std::future 对象进行等待 wait_for(),并根据返回判断是否 std::future_status::ready / std::future_status::deferred。
milliseconds 是 std::chrono::duration
#include
#include
#include
#include
#include
#include
auto someTask() -> int
{
std::cout << "wait." << std::endl;
// std::chrono::duration>
auto times = std::chrono::milliseconds(4000);
std::this_thread::sleep_for(times);
return 1;
}
auto main() -> int
{
std::future<int> f = std::async(someTask);
if (f.wait_for(std::chrono::milliseconds(3500)) == std::future_status::ready)
{
std::cout << f.get() << std::endl;
}
return 0;
}
多线程除却条件阻塞,还可以运用延时阻塞实现程序运行逻辑,对于某些实现是必须掌握的。C++的时钟类已经较为全面,只是稍显复杂,但运用并不困难。结合future的等待函数即返回状态,可方便的进行延时逻辑的实现。
参考文献:C++并发编程实战(第2版)[英] 安东尼•威廉姆斯(Anthony Williams)