• 2022-08-19 C++并发编程(十二)



    前言

    多线程的程序执行时阻塞可以是某条件达成,也可以是限时等待。

    比如延时超时,等待某个时长后程序进行下一个语句,或者绝对超时,在某个时间点进行下一步执行语句。

    我们先从时钟类开始介绍。


    一、时钟类

    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    可通过 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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    当前时刻可以是系统时钟,恒稳时钟,最高精度时钟(不一定有独立定义)。

    二、线程中使用延时等待

    我们可以在线程函数中进行等待 std::this_thread::sleep_for(),同时在 std::future 对象进行等待 wait_for(),并根据返回判断是否 std::future_status::ready / std::future_status::deferred。

    milliseconds 是 std::chrono::duration> 的 typedef。

    #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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    总结

    多线程除却条件阻塞,还可以运用延时阻塞实现程序运行逻辑,对于某些实现是必须掌握的。C++的时钟类已经较为全面,只是稍显复杂,但运用并不困难。结合future的等待函数即返回状态,可方便的进行延时逻辑的实现。

    参考文献:C++并发编程实战(第2版)[英] 安东尼•威廉姆斯(Anthony Williams)

  • 相关阅读:
    软件测试误区
    [HJ56 完全数计算]
    10.String 类的常用方法都有那些?
    vue或webpack加载highcharts与highcharts-3d
    相同wifi下,笔记本连接台式机上的虚拟机
    GBase 8a UNION用法
    自然语言处理从零到入门 BERT
    冰冰学习笔记:进程控制
    图解HTTP笔记整理(前六章)
    Spring MVC ViewNameMethodReturnValueHandler原理解析
  • 原文地址:https://blog.csdn.net/m0_54206076/article/details/126417100