一、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
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>中
-
-
#include <unistd.h>
-
#include<sys/stat.h>
-
#include<fcntl.h>
-
#include <linux/param.h>
-
#include <limits.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
-
#include <time.h>
-
#include <sys/time.h>
-
-
#include <fstream>
-
#include <sstream>
-
#include <istream>
-
#include <iterator>
-
-
#include <vector>
-
#include <string>
-
-
#include <iostream>
-
-
-
-
#endif
-
-
using
namespace std;
-
-
-
-
-
std::string timetostring(time_t nt)
-
{
-
tm time_in;
-
-
-
localtime_r(&nt, &time_in);
-
-
tm *tm_ = &time_in;
// 将time_t格式转换为tm结构体
-
-
int year, month, day, hour, minute, second;
// 定义时间的各个int临时变量。
-
year = tm_->tm_year +
1900;
// 临时变量,年,由于tm结构体存储的是从1900年开始的时间,所以临时变量int为tm_year加上1900。
-
month = tm_->tm_mon +
1;
// 临时变量,月,由于tm结构体的月份存储范围为0-11,所以临时变量int为tm_mon加上1。
-
day = tm_->tm_mday;
-
hour = tm_->tm_hour;
-
minute = tm_->tm_min;
-
second = tm_->tm_sec;
-
-
char s[
20];
// 定义总日期时间char*变量。
-
sprintf(s,
"%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second);
// 将年月日时分秒合并。
-
std::string str(s);
// 定义string变量,并将总日期时间char*变量作为构造函数的参数传入。
-
return std::
move(str);
// 返回转换日期时间后的string变量。
-
}
-
-
-
int f(pid_t pid)
-
{
-
int fd;
-
char buff[
128];
-
char *p;
-
unsigned
long uptime;
-
struct
timeval tv;
-
static
time_t boottime;
-
time_t now =
time(
0);
-
-
if ((fd =
open(
"/proc/uptime",
0)) !=
-1)
-
{
-
if (
read(fd, buff,
sizeof(buff)) >
0)
-
{
-
uptime =
strtoul(buff, &p,
10);
-
gettimeofday(&tv,
0);
-
boottime = tv.tv_sec - uptime;
-
}
-
close(fd);
-
}
-
-
-
ifstream procFile;
-
-
char stat[
255];
-
sprintf(stat,
"/proc/%d/stat", pid);
-
-
procFile.
open(stat);
-
-
char str[
255];
-
procFile.
getline(str,
255);
// delim defaults to '\n'
-
-
-
vector<string> tmp;
-
istringstream iss(str);
-
copy(
istream_iterator<string>(iss),
-
istream_iterator<string>(),
-
back_inserter<vector<string> >(tmp));
-
cout<<
"now"<<now<<endl;
-
cout<<
"boottime"<<boottime<<endl;
-
for(
int i=
0;i<tmp.
size();i++)
-
{
-
cout<< i <<
" : " <<tmp[i]<<endl;
-
}
-
-
-
cout<<
"CLOCKS_PER_SEC"<<CLOCKS_PER_SEC<<endl;
-
auto lstStr = tmp.
at(
21);
-
cout<<lstStr<<endl;
-
auto duration = (
atof(tmp.
at(
21).
c_str()))/HZ;
//其实是100
-
auto start_time = boottime + duration;
-
auto startStr =
timetostring(start_time);
-
-
printf(
"start: %d\n", start_time);
-
-
cout<<
"result:"<<startStr<<endl;
-
}
-
-
-
int main(int argc, char** argv)
-
{
-
int pid =
1;
-
if(argc>
1)
-
{
-
pid =
atoi(argv[
1]);
-
}
-
-
auto t=
f(pid);
-
-
getchar();
-
return
0;
-
}
参考:
linux内核中的HZ介绍_BAT-Battle的博客-CSDN博客_hz linux
三、linux应用获取boottime的两种方式
第一种:
-
-
struct timespec outtime;
memset(&outtime, 0x00, sizeof(struct timespec ));
clock_gettime(CLOCK_MONOTONIC, &outtime);
boottime = outtime.tv_sec * 1000000000 + outtime.tv_nsec
);
第二种:
-
if ((fd = open("/proc/uptime", 0)) != -1)
-
{
-
if (
read(fd, buff,
sizeof(buff)) >
0)
-
{
-
bootime=
strtoul(buff, &p,
10);