Linux应用层获取时间

一、linux支持的时钟类型

/*
 * The IDs of the various system clocks (for POSIX.1b interval timers):
 */
/*
 * A settable system-wide real-time clock.
 * 墙上时间,修改系统时间将直接影响该时间,但不受suspend影响
 */
#define CLOCK_REALTIME          0
/*
 * CLOCK_MONOTONIC
 * A nonsettable monotonically increasing clock that measures
 * time from some unspecified point in the past that does not
 * change after system startup.
 * 本时间 在系统suspend期间不计时
 */
#define CLOCK_MONOTONIC         1
/*
 * CLOCK_PROCESS_CPUTIME_ID
 * A clock that measures (user and system) CPU time
 * consumed by(all of the threads in) the calling process.
 */
#define CLOCK_PROCESS_CPUTIME_ID    2
/*
 * CLOCK_THREAD_CPUTIME_ID
 * A clock that measures (user and system) CPU time consumed
 * by(all of the threads in) the calling thread.
 */
#define CLOCK_THREAD_CPUTIME_ID     3


/*
 * CLOCK_MONOTONIC_RAW
 * 和 CLOCK_MONOTONIC很类似,区别点在于:
 * CLOCK_MONOTONIC在系统suspend状态下不计时;
 * CLOCK_MONOTONIC_RAW在系统suspend状态下仍然计时
 */
#define CLOCK_MONOTONIC_RAW     4
/*
 * CLOCK_REALTIME_COARSE
 * 和CLOCK_REALTIME类似,前者是后者的一个简化版本,前者精度较差,但性能比后者要好
 */
#define CLOCK_REALTIME_COARSE       5
/*
 * CLOCK_MONOTONIC_COARSE
 * 和CLOCK_MONOTONIC类似,前者是后者的一个简化版本,前者精度较差,但性能比后者要好
 */
#define CLOCK_MONOTONIC_COARSE      6
/*
 * CLOCK_BOOTTIME
 * Like CLOCK_MONOTONIC, this is a monotonically increasing
 * clock.  However, whereas the CLOCK_MONOTONIC clock does not
 * measure the time while a system is suspended, the
 * CLOCK_BOOTTIME clock does include the time during which the
 * system is suspended.  This is useful for applications that
 * need to be suspend-aware.  CLOCK_REALTIME is not suitable for
 * such applications, since that clock is affected by
 * discontinuous changes to the system clock.
 * 记录启动以来一共经历的时间,不受suspend、时间改变等其他因素影响
 * 一旦开机,该时间就随墙上时间一直单调、递增
 */
#define CLOCK_BOOTTIME          7
/*
 * CLOCK_REALTIME_ALARM
 * This clock is like CLOCK_REALTIME, but will wake the system if
 * it is suspended.  The caller must have the CAP_WAKE_ALARM
 * capability in order to set a timer against this clock.
 * 与CLOCK_REALTIME相似,但是_ALARM版本的CLOCK类型会唤醒系统
 */
#define CLOCK_REALTIME_ALARM        8
/*
 * CLOCK_BOOTTIME_ALARM
 * This clock is like CLOCK_BOOTTIME, but will wake the system if
 * it is suspended.  The caller must have the CAP_WAKE_ALARM
 * capability in order to set a timer against this clock.
 * 与CLOCK_BOOTTIME相似,但是_ALARM版本的CLOCK类型会唤醒系统
 */
#define CLOCK_BOOTTIME_ALARM        9

二、从/proc/{pid}/stat中获取启动时间,转化成字符串

stat 中的内容介绍,可参考 /proc/stat解析_houzhizhen的博客-CSDN博客_proc stat


 
 
  1. oscar:/ # cat /proc/1301/stat 1301 (aplogd) S 1 1301 0 0 -1 1077936384 1394 0 6 0 1593 1669 0 0 20 0 2 0 2267 11123691520 1209 18446744073709551615 402020179968 402020214704 549213869440 0 0 0 0 0 1073775864 0 0 0 17 5 0 0 5 0 0 402020223208 402020223208 402947661824 549213872290 549213872309 549213872309 549213876197 0

HZ是一个宏,定义在<linux/param.h>中


 
 
  1. #include <unistd.h>
  2. #include<sys/stat.h>
  3. #include<fcntl.h>
  4. #include <linux/param.h>
  5. #include <limits.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <time.h>
  9. #include <sys/time.h>
  10. #include <fstream>
  11. #include <sstream>
  12. #include <istream>
  13. #include <iterator>
  14. #include <vector>
  15. #include <string>
  16. #include <iostream>
  17. #endif
  18. using namespace std;
  19. std::string timetostring(time_t nt)
  20. {
  21. tm time_in;
  22. localtime_r(&nt, &time_in);
  23. tm *tm_ = &time_in; // 将time_t格式转换为tm结构体
  24. int year, month, day, hour, minute, second; // 定义时间的各个int临时变量。
  25. year = tm_->tm_year + 1900; // 临时变量,年,由于tm结构体存储的是从1900年开始的时间,所以临时变量int为tm_year加上1900。
  26. month = tm_->tm_mon + 1; // 临时变量,月,由于tm结构体的月份存储范围为0-11,所以临时变量int为tm_mon加上1。
  27. day = tm_->tm_mday;
  28. hour = tm_->tm_hour;
  29. minute = tm_->tm_min;
  30. second = tm_->tm_sec;
  31. char s[ 20]; // 定义总日期时间char*变量。
  32. sprintf(s, "%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second); // 将年月日时分秒合并。
  33. std::string str(s); // 定义string变量,并将总日期时间char*变量作为构造函数的参数传入。
  34. return std:: move(str); // 返回转换日期时间后的string变量。
  35. }
  36. int f(pid_t pid)
  37. {
  38. int fd;
  39. char buff[ 128];
  40. char *p;
  41. unsigned long uptime;
  42. struct timeval tv;
  43. static time_t boottime;
  44. time_t now = time( 0);
  45. if ((fd = open( "/proc/uptime", 0)) != -1)
  46. {
  47. if ( read(fd, buff, sizeof(buff)) > 0)
  48. {
  49. uptime = strtoul(buff, &p, 10);
  50. gettimeofday(&tv, 0);
  51. boottime = tv.tv_sec - uptime;
  52. }
  53. close(fd);
  54. }
  55. ifstream procFile;
  56. char stat[ 255];
  57. sprintf(stat, "/proc/%d/stat", pid);
  58. procFile. open(stat);
  59. char str[ 255];
  60. procFile. getline(str, 255); // delim defaults to '\n'
  61. vector<string> tmp;
  62. istringstream iss(str);
  63. copy( istream_iterator<string>(iss),
  64. istream_iterator<string>(),
  65. back_inserter<vector<string> >(tmp));
  66. cout<< "now"<<now<<endl;
  67. cout<< "boottime"<<boottime<<endl;
  68. for( int i= 0;i<tmp. size();i++)
  69. {
  70. cout<< i << " : " <<tmp[i]<<endl;
  71. }
  72. cout<< "CLOCKS_PER_SEC"<<CLOCKS_PER_SEC<<endl;
  73. auto lstStr = tmp. at( 21);
  74. cout<<lstStr<<endl;
  75. auto duration = ( atof(tmp. at( 21). c_str()))/HZ; //其实是100
  76. auto start_time = boottime + duration;
  77. auto startStr = timetostring(start_time);
  78. printf( "start: %d\n", start_time);
  79. cout<< "result:"<<startStr<<endl;
  80. }
  81. int main(int argc, char** argv)
  82. {
  83. int pid = 1;
  84. if(argc> 1)
  85. {
  86. pid = atoi(argv[ 1]);
  87. }
  88. auto t= f(pid);
  89. getchar();
  90. return 0;
  91. }

参考:

linux内核中的HZ介绍_BAT-Battle的博客-CSDN博客_hz linux

三、linux应用获取boottime的两种方式

第一种:


 
 
  1. struct timespec outtime; memset(&outtime, 0x00, sizeof(struct timespec )); clock_gettime(CLOCK_MONOTONIC, &outtime); boottime = outtime.tv_sec * 1000000000 + outtime.tv_nsec ); 第二种:
    
          
          
    1. if ((fd = open("/proc/uptime", 0)) != -1)
    2. {
    3. if ( read(fd, buff, sizeof(buff)) > 0)
    4. {
    5. bootime= strtoul(buff, &p, 10);
    • 0
      点赞
    • 2
      收藏
      觉得还不错? 一键收藏
    • 1
      评论
    评论 1
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值