C++有时间限制的等待

#define _CRT_SECURE_NO_WARNINGS 
// 之前介绍的所有阻塞调用都会无限期地阻塞,直到等待的事件发生,线程才会被唤醒。但在某些情况下,可能希望设置一个等待时间的限制。
#include <iostream>
#include<thread>
#include<mutex>
#include<chrono>
#include <iomanip>
#include <future>
#include<condition_variable>
//对于C++标准库而已,时钟提供四种信息:当前时间、时间点类型、时钟tick周期、是否为稳定时钟]
//特定时钟的时间点类型由 time_point 成员类型定义,因此 some_clock::now() 的返回类型是 some_clock::time_point

void Test1() {

    //通过调用静态成员函数now可以返回系统当前的时间
    //系统时钟
    std::chrono::system_clock::time_point time = std::chrono::system_clock::now(); //返回值,可以用auto缩短
    std::time_t now_c = std::chrono::system_clock::to_time_t(time); //把tim转为time_t类型
    //std::localtime(&now_c) 将 std::time_t 格式的时间转换为 struct tm* 结构体,以便后续用于格式化。
    std::cout << "当前时间为:" << std::put_time(std::localtime(&now_c), "%Y-%m-%d %X")<<"\n"; //格式化

    //查看系统时钟是否是稳定的
    bool isSteady = std::chrono::system_clock::is_steady; 
    std::cout << "系统时钟是否稳定: " << (isSteady ? "是" : "否") << "\n";
   
    //除了系统时钟,chrono库内还有很多时钟
    
    //查看steady_clock时钟是否是稳定的
    isSteady = std::chrono::steady_clock::is_steady;
    std::cout << "稳定时钟是否稳定: " << (isSteady ? "是" : "否") << "\n";

    //查看high_resolution_clock时钟是否是稳定的
    isSteady = std::chrono::high_resolution_clock::is_steady;
    std::cout << "高精度时钟是否稳定: " << (isSteady ? "是" : "否") << "\n";
}
//std::chrono::duration 是一个模板类,使用时需要指定两个模板参数:
//第一个参数是表示时间长度的数据类型(通常是整数类型,如 int, long, std::chrono::seconds::rep 等)。
//第二个参数是时间单位,可以是 std::ratio 类型(如 std::ratio<1> 表示一秒,std::milli 表示一毫秒等)。
void Test2() {
    //准库中预定义了多种时长别名,如nano、milli、microseconds等,方便用户快速使用。
    
    //定义一个1s秒持续时间
    std::chrono::duration<int,std::nano> du1(1); //第二个参数不定义的话,默认为秒
    std::cout << "秒:" << du1.count() << "\n";

    //定义一个500ms的时间
    std::chrono::duration <double>du2(0.5);  //仍然使用秒
    std::cout << "秒:" << du2.count() << "\n";
    std::chrono::duration<int, std::milli>du3(500); //直接使用毫秒
    std::cout << "毫秒:" << du3.count() << "\n";

    //定义一个100微秒的时间
    std::chrono::duration <int,std::micro>du7(100);  
    std::cout << "微秒:" << du7.count() << "\n";

    //std::chrono::duration重载了+-运算符和比较运算符
    std::chrono::duration<double,std::milli> du4 = du2 + du3; //毫秒+秒 = 输出为毫秒
    std::cout << "du4毫秒:" << du4.count() << "\n";
    auto du5 = du2 - du1;//秒-秒 =(输出)秒 
    std::cout << "du5秒:" << du5.count() << "\n";

    //使用std::ratio的比率来定义时间单位
    std::chrono::duration<int, std::ratio<1, 1000>>d(10); //这里1/1000s =1ms
    std::cout << "毫秒:" << d.count() << "\n";
    std::chrono::duration<int, std::ratio<60, 1>>d2(5); //这里60/1 = 60s=1min
    std::cout << "分钟:" << d2.count() << "\n";




    bool flag1 = du4 > du5;
    std::cout << "du4>du5:"<<flag1 << "\n";
    bool flag2 = du2 == du1;
    std::cout << "du2==du1:" << flag2 << "\n";

    //两个clock_point相减得到一个duration
    std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
    std::this_thread::sleep_for(std::chrono::seconds(1)); //休眠1s
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); 

    std::chrono::duration<double,std::milli> elapsed_time = end - start;//这里相减返回一个duration
    std::cout << "持续了" << elapsed_time.count() << "ms\n";
}
void Test3() {
    //为了方便C++14引入了 std::chrono_literals 命名空间,提供了许多预定义字面量后缀
    using namespace std::chrono_literals;
    //这里可以直接使用
    auto one_day = 24h;
    auto half_an_hour = 30min;
    auto thirty_second = 30s;

    //避免了很长的前缀
    std::chrono::duration<double, std::ratio<60, 1>> minute(30);
    //又或者避免了使用std::nanosecond,本质上nanosecond也是预先使用using语句换名的,所以本质上是一样的
    std::chrono::nanoseconds second(30);
    std::cout << "秒:" << second.count() << " == " << thirty_second.count() << "\n";
    std::cout << "分钟:" << minute.count() << " == " << half_an_hour.count() << "\n";

    //可以使用std::chrono::duration_cast<>进行显示的类型转换
    std::chrono::milliseconds ms(54802);
    std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(ms);//这里会截断
    std::cout << "54802ms = " << s.count() << "s" << "\n";
}
//基于持续时间的等待
void do_something() {
    std::cout << "进行其他任务\n";
}
void time_out() {
    std::cout << "超时了!进行超时的任务\n";
}
void delay_task() {
    std::cout << "任务被延迟!进行延迟的任务\n";
}
void wait_something() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
}
void Test4() {
    auto f = std::async(wait_something);
    //任务延迟
   // auto f = std::async(std::launch::deferred,wait_something);
    
    //wait_for返回一个future_status
   // wait_for如果等待超时,则返回 std::future_status::timeout;
     //如果期值已准备好,则返回 std::future_status::ready;
     //如果期值的任务被推迟,则返回 std::future_status::deferred。

    //std::future_status status = f.wait_for(std::chrono::milliseconds(500));//最多等0.5s
    std::future_status status = f.wait_for(std::chrono::seconds(2));//最多等2s
    if (status == std::future_status::ready) {
        do_something();
    }
    else if (status == std::future_status::timeout) {
        time_out();
    }
    else { //任务被延迟
        delay_task();
    }
}
//时钟的时间点由 std::chrono::time_point<> 类模板的实例表示
//std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>第一个参数是时钟类型,第二个参数是时钟单位(一般是秒或更小)
void calculate() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
}
void Test5() {
    //系统时间点
    std::chrono::system_clock::time_point start =std::chrono::system_clock::now(); //获取当前时间点
    calculate();
    auto end = std::chrono::system_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); //单位是微秒
    
    std::cout << "系统时钟:caculate函数花费了:" << duration.count()<< "ms 的时间\n"; //单位是微秒

    //稳定时间点
    std::chrono::steady_clock::time_point st = std::chrono::high_resolution_clock::now();
    calculate();
    auto ed = std::chrono::steady_clock::now();

    auto d = std::chrono::duration_cast<std::chrono::milliseconds>(ed-st);
    std::cout << "稳定时钟:caculate函数花费了:" << d.count() << "ms 的时间\n"; //单位是微秒

    //最高精度时间点
    std::chrono::high_resolution_clock::time_point begin= std::chrono::high_resolution_clock::now();
    calculate();
    auto over = std::chrono::high_resolution_clock::now();

    auto du = std::chrono::duration_cast<std::chrono::milliseconds>(over - begin);
    std::cout << "高精度时钟:caculate函数花费了:" << du.count() << "ms 的时间\n"; //单位是微秒
}
std::condition_variable cv; //条件变量,用于唤醒线程
bool done; //设置完成标签,如果完成了就填充为true
std::mutex m; //互斥锁,和条件变量配合使用
void do_work() {
    std::lock_guard lk(m); //上锁
    std::this_thread::sleep_for(std::chrono::milliseconds(800)); //模拟时间
    std::cout << "事件执行完毕!\n";
    done = true;
    cv.notify_one(); //提醒线程
}
bool wait_loop() {
    auto const timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(500); //最多等待500ms
    bool flag = true;
    std::unique_lock lk(m);
    while (!done) { //不断检查,直到任务完成或超时
        if (cv.wait_until(lk, timeout) == std::cv_status::timeout) { //如果时间到了的话
            flag = false;
            break;
        }
    }
    return flag; //查看是否超时
}
void Test6() {
    std::thread t1(do_work); 
    if (wait_loop()) {
        std::cout << "未超时!\n";
    }
    else {
        std::cout << "超时!\n";
    }
    t1.join();
}
//这里补充一下this_thread::sleep_until的用法
void Test7() {
    //std::this_thread::sleep_until接受一个时间点time_point
    auto start = std::chrono::system_clock::now();
    std::time_t now_c = std::chrono::system_clock::to_time_t(start+ std::chrono::seconds(2)); //把tim转为time_t类型
    std::cout << "休眠直至到时间:" << std::put_time(std::localtime(&now_c), "%Y-%m-%d %X") << "为止\n";
    std::this_thread::sleep_until(start + std::chrono::seconds(2)); //睡眠直到某个时间点
    std::cout << "线程被唤醒!执行任务\n";\
}
int main(){
    //Test1();
   // Test2();
   // Test3();
   //Test4();
   //Test5();
   //Test6();
    Test7();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值