linux下C++11时间操作

C++11中引入了chrono命名空间来处理时间相关的功能,该功能的引入极大的方便了开发人员对时间的操作。初次接触chrono,感觉会有点陌生,下来让我带你开启chrono的使用之旅。

1.chrono包含部分

chrono中主要包含时钟,时间点和时间间隔三部分。

(1)时钟

std::chrono::steady_clock  //相对时钟

std::chrono::system_clock //绝对时钟

(2)时间点

std::chrono::steady_clock::time_point  //相对时间点

std::chrono::system_clock::time_point // 绝对时间点

(3)时间间隔

std::chrono::nanoseconds        //纳秒
std::chrono::microseconds       //微妙
std::chrono::milliseconds       //毫秒
std::chrono::seconds            //秒
std::chrono::minutes            //分
std::chrono::hours              //时

2.chrono使用

#include <iostream>
#include <ctime>
#include <iomanip> //std::put_time  std::get_time
#include <chrono>
#include <sstream>
#include <thread>  //std::this_thread::sleep_for
#include <sys/time.h>

void testTime() {
    //时间间隔: duration 时钟: clocks   时间点: time point
    //计算时间间隔,相对时间
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    std::chrono::nanoseconds ndur = end - begin;
    std::cout << ndur.count() << std::endl;
    // 时间间隔默认是纳秒,要计算到秒,需要使用chrono自带的强制转换类型
    std::chrono::seconds sdur = std::chrono::duration_cast<std::chrono::seconds>(end - begin);
    std::cout << sdur.count() << std::endl;

    //获取系统时间,绝对时间,time_point与time_t互转, 显示时间
    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
    //获取两天以后的时间,得到time_t类型
    time_t after = std::chrono::system_clock::to_time_t(now + std::chrono::hours(48));
    std::chrono::system_clock::time_point after_point = std::chrono::system_clock::from_time_t(after);
    //打印两天以后的经过的纳秒
    std::cout << (after_point - now).count() << std::endl;
    std::cout << std::chrono::duration_cast<std::chrono::hours>(after_point - now).count() << std::endl;

    //时间格式化
    std::time_t seond_now = std::chrono::system_clock::to_time_t(now);
    std::stringstream ss;

    //time_t -> ss
	ss << std::put_time(std::localtime(&seond_now), "%Y-%m-%d %H:%M:%S");
    std::string strTime = ss.str();
    std::cout << "put_time::" << strTime << std::endl;
    std::cout << std::put_time(std::localtime(&seond_now), "%F %T") <<std::endl;
    std::cout << ss.str() << std::endl;

    time_t rawtime;
	struct tm info;
    //std::localtime是非线程安全的,linux下建议使用localtime_r,windows下使用localtime_s
    localtime_r(&seond_now, &info);//将time_t转为tm

    char buffer[80];
    //ctime是非线程安全的,C标准也建议使用strftime,不要使用ctime、ctime_s
    std::strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", &info);
    std::cout << "strftime::" << buffer << std::endl;

    struct tm tm_now;
    //ss -> tm
	ss >> std::get_time(&tm_now, "%Y-%m-%d %H:%M:%S");

    strTime = ss.str();
    std::cout << "get_time:: " << strTime << std::endl;

    //将tm转为time_t
    time_t dd = std::mktime(&tm_now);
    std::cout << "mktime::" << dd << std::endl;

    //时间戳打印显示
    //utc
    uint64_t seconds1 = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    std::cout << seconds1 << std::endl;
    //相对时间
    uint64_t seconds2 = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
    std::cout << seconds2 << std::endl;

    struct timeval tv;
    gettimeofday(&tv, NULL);
    //秒
    uint64_t timestamp1 = tv.tv_sec;
    //毫秒
    uint64_t timestamp2 = tv.tv_sec * 1000 + tv.tv_usec / 1000;
    //微秒
    uint64_t timestamp3 = tv.tv_sec * 1000 * 1000 + tv.tv_usec;
    std::cout << timestamp1 << " " << timestamp2 << " " << timestamp3 << std::endl;
    printf("%ld, %ld, %ld\n", timestamp1, timestamp2, timestamp3);

    timestamp1 = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    timestamp2 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    timestamp3 = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    std::cout << timestamp1 << " " << timestamp2 << " " << timestamp3 << std::endl;
    printf("%ld, %ld, %ld\n", timestamp1, timestamp2, timestamp3);
}

int main ()
{
    testTime();
    return 0;
}

运行结果如下:

 

说明:

(1)chrono没有提供时间格式化的操作,格式得到指定格式的字符串需要使用std::put_time或者std::strftime 

(2)std::localtime返回静态struct tm *类型对象,是非线程安全的,所以为了程序的健壮性,在linux下使用localtime_r,windows下使用localtime_s

(3)std::put_time时间可以存放在stringstream中,std::get_time从stringstream中获取时间信息,其使用是对应的

(4)std::chrono::steady_clock:相对时钟,不会因为修改了系统时间而变化,功能类似于平时生活中的计时秒表。std::chrono::system_clock是系统时钟,对系统有依赖,系统时间修改其也会发生变化。所以std::chrono::steady_clock在实际开发中用来统计耗时,std::chrono::system_clock用来获取系统时间。chrono

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Linux C中实现定时器,我们可以使用信号处理机制来实现。具体步骤如下: 1. 引入头文件:包括<sys/time.h> 和 <signal.h>。 2. 定义信号处理函数:在信号处理函数中定义定时器到期时的操作。例如,可以在信号处理函数中输出一条定时器到期的消息。 3. 设置定时器:使用setitimer函数来设置定时器的间隔时间和初始启动时间,并指定信号处理函数。setitimer函数需要传入一个结构体itimerval作为参数,该结构体包含两个成员:it_value代表第一次到期的时间,it_interval代表后续到期的时间间隔。 4. 阻塞信号:使用sigaction函数阻塞相关信号,以免在处理定时器到期时被其他信号打断。 5. 开启定时器:使用信号处理函数来触发定时器,并在定时器到期时执行相关操作。 以下是一个简单的示例代码: ```C #include <stdio.h> #include <sys/time.h> #include <signal.h> void timer_handler(int signum) { printf("Timer expired!\n"); } int main() { struct itimerval timer; // 设置定时器间隔为2秒,并初始化定时器 timer.it_value.tv_sec = 2; timer.it_value.tv_usec = 0; timer.it_interval.tv_sec = 2; timer.it_interval.tv_usec = 0; // 设置信号处理函数 signal(SIGALRM, timer_handler); // 设置定时器 setitimer(ITIMER_REAL, &timer, NULL); // 阻塞相关信号 sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGALRM); sigprocmask(SIG_BLOCK, &mask, NULL); // 循环等待定时器到期 while(1) { pause(); } return 0; } ``` 以上代码中,我们通过设置定时器的间隔时间和初始启动时间来控制定时器的重复触发。在信号处理函数中,我们通过输出一条消息来表示定时器到期的事件。在主函数中,我们首先设置信号处理函数,然后设置定时器并开启定时器,并最后通过循环等待定时器到期来保持程序的运行。 ### 回答2: 在Linux C编程中,实现定时器可以使用信号机制来达到目的。下面是一个简单的例子,展示了如何实现一个定时器。 首先,需要包含头文件`<unistd.h>`和`<signal.h>`,以便使用相关的函数和宏定义。 然后,定义一个用于处理定时器的信号处理函数,例如命名为`timer_handler`。在这个函数中,可以执行特定的操作作为定时器触发后的处理逻辑。在下面的例子中,我们只是简单地打印一条消息。 接下来,创建一个`timer_t`类型的变量,用于存储定时器的ID。可以使用`timer_create`函数创建一个新的定时器,并传入相关的参数,如定时器类型、信号处理函数等。 然后,使用`timer_settime`函数设置定时器的时间参数,包括初始时间和间隔时间。在下面的例子中,我们将定时器设置为3秒后启动,并且每隔5秒触发一次。 最后,使用`sleep`函数使程序暂停,以便触发定时器。在实际应用中,可以根据需要将这个定时器与其他功能集成。 下面是一个完整的例子代码: ```c #include <unistd.h> #include <signal.h> #include <stdio.h> void timer_handler(int signum) { printf("Timer expired.\n"); } int main() { // 创建一个新的定时器 timer_t timerid; struct sigevent sev; struct itimerspec its; sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGALRM; sev.sigev_value.sival_ptr = &timerid; timer_create(CLOCK_REALTIME, &sev, &timerid); // 设置定时器参数 its.it_value.tv_sec = 3; its.it_value.tv_nsec = 0; its.it_interval.tv_sec = 5; its.it_interval.tv_nsec = 0; timer_settime(timerid, 0, &its, NULL); // 暂停程序,等待定时器触发 sleep(20); return 0; } ``` 在上述的例子中,我们创建了一个3秒后启动的定时器,并且每隔5秒触发一次。程序将在主函数中的`sleep`函数处暂停20秒,期间定时器会触发三次,并打印"Timer expired."的消息。 ### 回答3: 在Linux C中,我们可以使用`timer_create()`函数来创建一个定时器。该函数接受四个参数:一个时钟ID,一个用于保存定时器 ID 的变量,一个结构体指针以指定定时器的属性,以及一个可选的回调函数。 要创建一个定时器,首先需要定义一个 `timer_t` 类型的变量来保存定时器 ID。然后,要使用 `timer_create()` 函数创建定时器,并将定时器 ID 保存到该变量中。 接下来,需要定义一个结构体变量来指定定时器的属性。可以使用 `struct sigevent` 结构体,并根据需要设置其成员变量。例如,我们可以将 `sigev_notify` 成员设置为 `SIGEV_THREAD`,以指定定时器到期时,将调用一个线程执行回调函数。 在回调函数中,可以执行想要执行的操作。可以在回调函数中做一些计算、输出等,或者执行某个函数或方法。 接下来,我们需要使用 `timer_settime()` 函数来启动定时器,并设置执行回调函数的时间间隔。此函数接受四个参数:定时器 ID、指定定时器何时到期的结构体指针、一个用于保存之前定时器设置的结构体指针,并通过第四个参数来指定相对于哪个时间来设置定时器。 综上所述,实现定时器的步骤如下: 1. 定义 `timer_t` 类型的变量来保存定时器 ID。 2. 使用 `timer_create()` 函数创建定时器。 3. 定义一个结构体变量来指定定时器的属性。 4. 在回调函数中定义要执行的操作。 5. 使用 `timer_settime()` 函数启动定时器,并设置执行回调函数的时间间隔。 需要注意的是,创建定时器的函数及相关数据结构在`<time.h>`头文件中声明。在使用定时器时,可能还需要使用信号和线程相关的函数和数据结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值