Linux下time/timestamp相关。

iptables基础-ping学习及禁用Time Exceeded包 iptables基础-ping允许其他主机ping本机允许本机ping其他主机 允许其他主机ping本机 允许其他主机ping本机 [root@localhost ~]# iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT [root@localhost ~]# iptables -A OUTPUT -p icmp --icmp... 阅读详情

 在Linux下面编程,经常要碰到用到与time/timestamp相关的东西,下面是我以前收集的,放在这里共享。

 

In the file: dbus-sysdeps-unix.c

/**

 * Get current time, as in gettimeofday().

 *

 * @param tv_sec return location for number of seconds

 * @param tv_usec return location for number of microseconds (thousandths)

 */

void

_dbus_get_current_time (long *tv_sec,

                        long *tv_usec)

{

  struct timeval t;

 

  gettimeofday (&t, NULL);

 

  if (tv_sec)

    *tv_sec = t.tv_sec;

  if (tv_usec)

    *tv_usec = t.tv_usec;

}

 

 

How to use it:

 

 

 

/**

 * Get current time, as in gettimeofday().

 *

 * @param tv_sec return location for number of seconds

 * @param tv_usec return location for number of microseconds (thousandths)

 */

void

_dbus_get_current_time (long *tv_sec,

                        long *tv_usec)

{

  struct timeval t;

 

  gettimeofday (&t, NULL);

 

  if (tv_sec)

    *tv_sec = t.tv_sec;

  if (tv_usec)

    *tv_usec = t.tv_usec;

}

 

 

Two time structures:

 

Struct timeval:

  struct   timeval  
  {  
          long   tv_sec;  
          long   tv_usec;  
  }  

 

 

 

 

 

 

 


 

14.11 我知道库函数 localtime() 可以把 time_t 转换成结构  struct tm, 而 ctime() 可以把 time_t 转换成为可打印的字符串。怎样才能进行反向操作, 把 struct tm 或一个字符串转换成 time_t?

ANSI C 提供了库函数 mktime(), 它把 struct tm 转换成 time_t。

把一个字符串转换成 time_t 比较难些, 这是由于可能遇到各种各样的日期和时间格式。某些系统提供函数 strptime(), 基本上是 strftime()  的反向函数。其它常用的函数有 partime() (与 RCS 包一起被广泛的发布) 和 getdate() (还有少数其它函数, 发布在 C 的新闻组)。参见问题  18.18。

 

 

C/C++中的日期和时间 time_t(cjp: long)与struct tm

2006-07-18 14:07

摘要:

http://wiseman.cnblogs.com
本文从介绍基础概念入手,探讨了在C/C++中对日期和时间操作所用到的数据结构和函数,并对计时、时间的获取、时间的计算和显示格式等方面进行了阐述。本文还通过大量的实例向你展示了time.h头文件中声明的各种函数和数据结构的详细使用方法。

关键字:UTC(世界标准时间),Calendar Time(日历时间),epoch(时间点),clock tick(时钟计时单元)


1
.概念
在C/C++中,对字符串的操作有很多值得注意的问题,同样,C/C++对时间的操作也有许多值得大家注意的地方。最近,在技术群中有很多网友也多次问到过C++语言中对时间的操作、获取和显示等等的问题。下面,在这篇文章中,笔者将主要介绍在C/C++中时间和日期的使用方法.

通过学习许多C/C++库,你可以有很多操作、使用时间的方法。但在这之前你需要了解一些“时间”和“日期”的概念,主要有以下几个:

Coordinated Universal Time
(UTC):协调世界时,又称为世界标准时间,也就是大家所熟知的格林威治标准时间(Greenwich Mean Time,GMT)。比如,中国内地的时间与UTC的时差为+8,也就是UTC+8。美国是UTC-5。

Calendar Time
:日历时间,是用“从一个标准时间点到此时的时间经过的秒数”来表示的时间。这个标准时间点对不同的编译器来说会有所不同,但对一个编译系统来说,这个标准时间点是不变的,该编译系统中的时间对应的日历时间都通过该标准时间点来衡量,所以可以说日历时间是“相对时间”,但是无论你在哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。

epoch
:时间点。时间点在标准C/C++中是一个整数,它用此时的时间和标准时间点相差的秒数(即日历时间)来表示。

clock tick
:时钟计时单元(而不把它叫做时钟滴答次数),一个时钟计时单元的时间长短是由CPU控制的。一个clock tick不是CPU的一个时钟周期,而是C/C++的一个基本计时单位。

我们可以使用ANSI标准库中的time.h头文件。这个头文件中定义的时间和日期所使用的方法,无论是在结构定义,还是命名,都具有明显的C语言风格。下面,我将说明在C/C++中怎样使用日期的时间功能。

2
. 计时

C/C++
中的计时函数是clock(),而与其相关的数据类型是clock_t。在MSDN中,查得对clock函数定义如下:

clock_t clock( void );

这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wall-clock)。其中clock_t是用来保存时间的数据类型,在time.h文件中,我们可以找到对它的定义:

#ifndef _CLOCK_T_DEFINED
typedef long clock_t;
#define _CLOCK_T_DEFINED
#endif

很明显,clock_t是一个长整形数。在time.h文件中,还定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:

#define CLOCKS_PER_SEC ((clock_t)1000)

CJP: #define CLOCKS_PER_SEC 1000000
// 1 million

标准C的库函数clock(或者C++中的ctime)返回的是clock_t类型的值,单位为CLOCKS_PER_SEC,在time.h头文件中定义。目前这个常数的值为100,这使得时间的精度很低,对于某些任务来说是不够的。CodeWarrior将CLOCKS_PER_SEC定义为1000000,可以得到毫秒级的精度。

 

 


可以看到每过千分之一秒(1毫秒),调用clock()函数返回的值就加1。下面举个例子,你可以使用公式clock()/CLOCKS_PER_SEC来计算一个进程自身的运行时间:

void elapsed_time()
{
printf("Elapsed time:%u secs./n",clock()/CLOCKS_PER_SEC);
}

当然,你也可以用clock函数来计算你的机器运行一个循环或者处理其它事件到底花了多少时间:

#i nclude “stdio.h”
#i nclude “stdlib.h”
#i nclude “time.h”

int main( void )
{
   long    i = 10000000L;
   clock_t start, finish;
   double  duration;
   /*
测量一个事件持续的时间*/
   printf( "Time to do %ld empty loops is ", i );
   start = clock();
   while( i-- )      ;
   finish = clock();
   duration = (double)(finish - start) / CLOCKS_PER_SEC;
   printf( "%f seconds/n", duration );
   system("pause");
}

在笔者的机器上,运行结果如下:

Time to do 10000000 empty loops is 0.03000 seconds

上面我们看到时钟计时单元的长度为1毫秒,那么计时的精度也为1毫秒,那么我们可不可以通过改变CLOCKS_PER_SEC的定义,通过把它定义的大一些,从而使计时精度更高呢?通过尝试,你会发现这样是不行的。在标准C/C++中,最小的计时单位是一毫秒。

3
.与日期和时间相关的数据结构

在标准C/C++中,我们可通过tm结构来获得日期和时间,tm结构在time.h中的定义如下:

#ifndef _TM_DEFINED
struct tm {
        int tm_sec;     /*
秒 – 取值区间为[0,59] */
        int tm_min;     /*
分 - 取值区间为[0,59] */
        int tm_hour;    /*
时 - 取值区间为[0,23] */
        int tm_mday;    /*
一个月中的日期 - 取值区间为[1,31] */
        int tm_mon;     /*
月份(从一月开始,0代表一月) - 取值区间为[0,11] */
        int tm_year;    /*
年份,其值等于实际年份减去1900 */
        int tm_wday;    /*
星期 – 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
        int tm_yday;    /*
从每年的1月1日开始的天数 – 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */
        int tm_isdst;   /*
夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。*/
        };
#define _TM_DEFINED
#endif

ANSI C
标准称使用tm结构的这种时间表示为分解时间(broken-down time)。

而日历时间(Calendar Time)是通过time_t数据类型来表示的,用time_t表示的时间(日历时间)是从一个时间点(例如:1970年1月1日0时0分0秒)到此时的秒数。在time.h中,我们也可以看到time_t是一个长整型数:

#ifndef _TIME_T_DEFINED
typedef long time_t;         /*
时间值 */
#define _TIME_T_DEFINED     /*
避免重复定义 time_t */
#endif

大家可能会产生疑问:既然time_t实际上是长整型,到未来的某一天,从一个时间点(一般是1970年1月1日0时0分0秒)到那时的秒数(即日历时间)超出了长整形所能表示的数的范围怎么办?对time_t数据类型的值来说,它所表示的时间不能晚于2038年1月18日19时14分07秒。为了能够表示更久远的时间,一些编译器厂商引入了64位甚至更长的整形数来保存日历时间。比如微软在Visual C++中采用了__time64_t数据类型来保存日历时间,并通过_time64()函数来获得日历时间(而不是通过使用32位字的time()函数),这样就可以通过该数据类型保存3001年1月1日0时0分0秒(不包括该时间点)之前的时间。

在time.h头文件中,我们还可以看到一些函数,它们都是以time_t为参数类型或返回值类型的函数:

double difftime(time_t time1, time_t time0);
time_t mktime(struct tm * timeptr);
time_t time(time_t * timer);
char * asctime(const struct tm * timeptr);
char * ctime(const time_t *timer);

此外,time.h还提供了两种不同的函数将日历时间(一个用time_t表示的整数)转换为我们平时看到的把年月日时分秒分开显示的时间格式tm:

struct tm * gmtime(const time_t *timer);                                          
struct tm * localtime(const time_t * timer);

通过查阅MSDN,我们可以知道Microsoft C/C++ 7.0中时间点的值(time_t对象的值)是从1899年12月31日0时0分0秒到该时间点所经过的秒数,而其它各种版本的Microsoft C/C++和所有不同版本的Visual C++都是计算的从1970年1月1日0时0分0秒到该时间点所经过的秒数。

4
.与日期和时间相关的函数及应用
在本节,我将向大家展示怎样利用time.h中声明的函数对时间进行操作。这些操作包括取当前时间、算时间间隔、以不同的形式显示时间等内容。

4.1
获得日历时间

我们可以通过time()函数来获得日历时间(Calendar Time),其原型为:

time_t time(time_t * timer);

如果你已经声明了参数timer,你可以从参数timer返回现在的日历时间,同时也可以通过返回值返回现在的日历时间,即从一个时间点(例如:1970年1月1日0时0分0秒)到现在此时的秒数。如果参数为空(NULL),函数将只通过返回值返回现在的日历时间,比如下面这个例子用来显示当前的日历时间:

#i nclude "time.h"
#i nclude "stdio.h"
int main(void)
{
struct tm *ptr;
time_t lt;
lt =time(NULL);
printf("The Calendar Time now is %d/n",lt);
return 0;
}

运行的结果与当时的时间有关,我当时运行的结果是:

The Calendar Time now is 1122707619

其中1122707619就是我运行程序时的日历时间。即从1970年1月1日0时0分0秒到此时的秒数。

4.2
获得日期和时间

这里说的日期和时间就是我们平时所说的年、月、日、时、分、秒等信息。从第2节我们已经知道这些信息都保存在一个名为tm的结构体中,那么如何将一个日历时间保存为一个tm结构的对象呢?

其中可以使用的函数是gmtime()和localtime(),这两个函数的原型为:

struct tm * gmtime(const time_t *timer);                                          
struct tm * localtime(const time_t * timer);

其中gmtime()函数是将日历时间转化为世界标准时间(即格林尼治时间),并返回一个tm结构体来保存这个时间,而localtime()函数是将日历时间转化为本地时间。比如现在用gmtime()函数获得的世界标准时间是2005年7月30日7点18分20秒,那么我用localtime()函数在中国地区获得的本地时间会比时间标准时间晚8个小时,即2005年7月30日15点18分20秒。下面是个例子:

#i nclude "time.h"
#i nclude "stdio.h"
int main(void)
{
struct tm *local;
time_t t;
t=time(NULL);
local=localtime(&t);
printf("Local hour is: %d/n",local->tm_hour);
local=gmtime(&t);
printf("UTC hour is: %d/n",local->tm_hour);
return 0;
}

运行结果是:

Local hour is: 15
UTC hour is: 7

4.3
固定的时间格式

我们可以通过asctime()函数和ctime()函数将时间以固定的格式显示出来,两者的返回值都是char*型的字符串。返回的时间格式为:

星期几 月份 日期 时:分:秒 年/n/0
例如:Wed Jan 02 02:03:55 1980/n/0

其中/n是一个换行符,/0是一个空字符,表示字符串结束。下面是两个函数的原型:

char * asctime(const struct tm * timeptr);
char * ctime(const time_t *timer);

其中asctime()函数是通过tm结构来生成具有固定格式的保存时间信息的字符串,而ctime()是通过日历时间来生成时间字符串。这样的话,asctime()函数只是把tm结构对象中的各个域填到时间字符串的相应位置就行了,而ctime()函数需要先参照本地的时间设置,把日历时间转化为本地时间,然后再生成格式化后的字符串。在下面,如果lt是一个非空的time_t变量的话,那么:

printf(ctime(<));

等价于:

struct tm *ptr;
ptr=localtime(<);
printf(asctime(ptr));

那么,下面这个程序的两条printf语句输出的结果就是不同的了(除非你将本地时区设为世界标准时间所在的时区):

#i nclude "time.h"
#i nclude "stdio.h"
int main(void)
{
struct tm *ptr;
time_t lt;
lt =time(NULL);
ptr=gmtime(<);
printf(asctime(ptr));
printf(ctime(<));
return 0;
}

运行结果:

Sat Jul 30 08:43:03 2005
Sat Jul 30 16:43:03 2005

4.4
自定义时间格式

我们可以使用strftime()函数将时间格式化为我们想要的格式。它的原型如下:

size_t strftime(
   char *strDest,
   size_t maxsize,
   const char *format,
   const struct tm *timeptr
);

我们可以根据format指向字符串中格式命令把timeptr中保存的时间信息放在strDest指向的字符串中,最多向strDest中存放maxsize个字符。该函数返回向strDest指向的字符串中放置的字符数。

函数strftime()的操作有些类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。格式化命令说明串strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。

%a
星期几的简写
%A
星期几的全称
%b
月分的简写
%B
月份的全称
%c
标准的日期的时间串
%C
年份的后两位数字
%d
十进制表示的每月的第几天
%D
月/天/年
%e
在两字符域中,十进制表示的每月的第几天
%F
年-月-日
%g
年份的后两位数字,使用基于周的年
%G
年分,使用基于周的年
%h
简写的月份名
%H 24
小时制的小时
%I 12
小时制的小时
%j
十进制表示的每年的第几天
%m
十进制表示的月份
%M
十时制表示的分钟数
%n
新行符
%p
本地的AM或PM的等价显示
%r 12
小时的时间
%R
显示小时和分钟:hh:mm
%S
十进制的秒数
%t
水平制表符
%T
显示时分秒:hh:mm:ss
%u
每周的第几天,星期一为第一天 (值从0到6,星期一为0)
%U
第年的第几周,把星期日做为第一天(值从0到53)
%V
每年的第几周,使用基于周的年
%w
十进制表示的星期几(值从0到6,星期天为0)
%W
每年的第几周,把星期一做为第一天(值从0到53)
%x
标准的日期串
%X
标准的时间串
%y
不带世纪的十进制年份(值从0到99)
%Y
带世纪部分的十制年份
%z
,%Z 时区名称,如果不能得到时区名称则返回空字符。
%%
百分号

如果想显示现在是几点了,并以12小时制显示,就象下面这段程序:

#i nclude “time.h”
#i nclude “stdio.h”
int main(void)
{
struct tm *ptr;
time_t lt;
char str[80];
lt=time(NULL);
ptr=localtime(<);
strftime(str,100,"It is now %I %p",ptr);
printf(str);
return 0;
}

其运行结果为:
It is now 4PM

而下面的程序则显示当前的完整日期:

#i nclude
#i nclude

void main( void )
{
        struct tm *newtime;
        char tmpbuf[128];
        time_t lt1;
        time( <1 );
        newtime=localtime(<1);
        strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year %Y./n", newtime);
        printf(tmpbuf);
}

运行结果:

Today is Saturday, day 30 of July in the year 2005.

4.5
计算持续的时间长度

有时候在实际应用中要计算一个事件持续的时间长度,比如计算打字速度。在第1节计时部分中,我已经用clock函数举了一个例子。Clock()函数可以精确到毫秒级。同时,我们也可以使用difftime()函数,但它只能精确到秒。该函数的定义如下:

double difftime(time_t time1, time_t time0);

虽然该函数返回的以秒计算的时间间隔是double类型的,但这并不说明该时间具有同double一样的精确度,这是由它的参数觉得的(time_t是以秒为单位计算的)。比如下面一段程序:

#i nclude “time.h”
#i nclude “stdio.h”
#i nclude “stdlib.h”
int main(void)
{
time_t start,end;
start = time(NULL);
system("pause");
end = time(NULL);
printf("The pause used %f seconds./n",difftime(end,start));//<-
system("pause");
return 0;
}

运行结果为:
请按任意键继续. . .
The pause used 2.000000 seconds.
请按任意键继续. . .

可以想像,暂停的时间并不那么巧是整整2秒钟。其实,你将上面程序的带有“//<-”注释的一行用下面的一行代码替换:

printf("The pause used %f seconds./n",end-start);

其运行结果是一样的。

4.6
分解时间转化为日历时间

这里说的分解时间就是以年、月、日、时、分、秒等分量保存的时间结构,在C/C++中是tm结构。我们可以使用mktime()函数将用tm结构表示的时间转化为日历时间。其函数原型如下:

time_t mktime(struct tm * timeptr);

其返回值就是转化后的日历时间。这样我们就可以先制定一个分解时间,然后对这个时间进行操作了,下面的例子可以计算出1997年7月1日是星期几:

#i nclude "time.h"
#i nclude "stdio.h"
#i nclude "stdlib.h"
int main(void)
{
struct tm t;
time_t t_of_day;
t.tm_year=1997-1900;
t.tm_mon=6;
t.tm_mday=1;
t.tm_hour=0;
t.tm_min=0;
t.tm_sec=1;
t.tm_isdst=0;
t_of_day=mktime(&t);
printf(ctime(&t_of_day));
return 0;
}

运行结果:

Tue Jul 01 00:00:01 1997

现在注意了,有了mktime()函数,是不是我们可以操作现在之前的任何时间呢?你可以通过这种办法算出1945年8月15号是星期几吗?答案是否定的。因为这个时间在1970年1月1日之前,所以在大多数编译器中,这样的程序虽然可以编译通过,但运行时会异常终止。

5
.总结

本文介绍了标准C/C++中的有关日期和时间的概念,并通过各种实例讲述了这些函数和数据结构的使用方法。笔者认为,和时间相关的一些概念是相当重要的,理解这些概念是理解各种时间格式的转换的基础,更是应用这些函数和数据结构的基础

 

 

GDate vs struct tm

起初没留心他们的区别,调试时郁闷了半天才陆续发现问题。忽略过程,只记结果
GDate.year == tm.tm_year + 1900
GDate.month == tm.tm_mon + 1
GDate.day == tm.tm_day

year的区别没有悬念,有特点的是month,居然也可以不同。

 

 

Linux 中的计时

 

文档选项

 

将此页作为电子邮件发送

未显示需要 JavaScript 的文档选项

 

 

拓展 Tomcat 应用

 

下载 IBM 开源 J2EE 应用服务器 WAS CE 新版本 V1.1

级别: 初级

车皓阳 (grandiose11@msn.com)中科院软件所

2003 年 10 月 01 日

本文描述了Linux系统中一些与计时相关的问题和解决方法。因为在学习和研究的过程中我们经常需要统计程序或程序段的耗时,评估它们的性能好坏。因而这些问题对于我们来说,经常会遇到。掌握多种计时方法对于开发人员或科研工作者来说都是必须掌握的一项技能。本文解决了在Linux计时当中经常会遇到的一些技术问题,相信会对他人的工作有所帮助。

实际上,可能还会有其它一些方法可以完成本文讨论的任务。我仅讨论了我所使用的方法,这并不意味着除此之外的其它方法就很差劲,只不过对我来说这些方法相对简单有效而已。

Linux中的时间

在Linux系统中,时间扮演着一个非常重要的角色,它几乎无处不在。开机时,会显示如下的信息:

Last login: Tue Sep 23 22:12:50 from 192.168.6.100
          

 

关机时,我们可以使用shutdown命令指定何时或多长时间后机器将会定时关闭。我们有可能还会设置一台Linux时间服务器与互联网上的一级或二级时间服务器同步,总之,在Linux系统中,我们必须要了解时间。

实际上,linux系统有着自己的计时器时钟。可以实验一下,分别执行date和/sbin/clock(或sbin/hwclock)命令,得到的时间是不同的。

[grandiose@Bygone grandiose]$ date
          
Sun Sep 28 21:11:02 EDT 2003
          
[grandiose@Bygone grandiose]$ /sbin/clock
          
Sun 28 Sep 2003 09:07:07 PM EDT  -0.466994 seconds
          

 

当你以 root 身份改变了系统时间之后,请记住以 clock -w 来将系统时间写入 CMOS 中。

 


 

使用C语言进行计时

在用户空间中可以使用C语言函数gettimeofday 得到时间,它的调用格式是:

#include <sys/time.h> 
          
int gettimeofday(struct timeval *tv, struct timezone *tz); 
          
int settimeofday(const struct timeval *tv , const struct timezone *tz);
          
        结构timeval的定义为:
           
strut timeval {
          
long tv_sec; /* 秒数 */
          
long tv_usec; /* 微秒数 */
          
};
          

 

可以看出,使用这种方式计时,精度可达微秒,也就是10-6秒。进行计时的时候,我们需要前后调用两次gettimeofday,然后计算中间的差值:

 
          
gettimeofday( &start, NULL );
          
foo(); 
          
gettimeofday( &end, NULL );
          
timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec; 
          
timeuse /= 1000000;
          

 


 

Shell计时

在Linux的Shell下,我们经常也使用Shell内置的time命令和GNU版的time命令来测试程序运行的时间。

内置的time提供的参数选项比较少,而GNU的time则提供了丰富的参数选项,包括指定输出文件等功能。

[grandiose@Bygone grandiose]$ /usr/bin/time --output=foo.txt foo
          

 

上句只有时间信息输出到了foo.txt文件中,如果想要包括foo执行的结果,就需要按下句这样使用:

 
          
[grandiose@Bygone grandiose]$ /usr/bin/time --output=foo.txt --append foo >foo.txt
          

 

如果想要控制输出时间的格式,可以使用-f开关进行格式化:

[grandiose@Bygone grandiose]$ /usr/bin/time --output=foo.txt -f "//t%E real,//t%U user,//t%S sys" foo
          

 

如果仍需要使用Shell内置的time命令,可以用下面一句将结果输出至文件:

[grandiose@Bygone grandiose]$ (time foo) 2>foo.txt
          

 

这样写是因为内置命令time的输出是到标准错误的,文件描述符2表示标准错误stderr。如果还想要包括foo执行的结果,就要这样:

[grandiose@Bygone grandiose]$ (time foo) >foo.txt 2>&1
          

 

其中2>&1的含义是2与1 相同,一起送入foo.txt中。

nohup命令可以保证进程在退出系统之后仍能运行,这是它的常规用法。我们也可以这样使用nohup:

[grandiose@Bygone grandiose]$ nohup time foo
          

 

结果全部输出至nohup.out,也包括程序运行的时间信息。可以使用下面的语句将时间信息输出至文件foo.txt中。

 
          
[grandiose@Bygone grandiose]$ tail -2 nohup.out > foo.txt
          

 

为了保证和POSIX一致,输出的时间格式为(nohup.out中的内容除外):

real    0m0.007s
          
user    0m0.002s
          
sys     0m0.004s
          

 

我们可以使用linux下面一些过滤命令如awk、sed、grep、tr等过滤出我们想要得到的内容,例如想要得到real段对应的时间:

[grandiose@Bygone grandiose]$ grep real foo.txt | cut -f2,或者
           
[grandiose@Bygone grandiose]$ sed -n '2p' foo.txt | cut -f2
          

 

在Shell下,输出的时间精度为毫秒级,如果需要微秒级的计时,那就应该在程序中进行处理。

 


 

内核空间中的计时

如果要定制自己的设备驱动程序,可能就会用到内核里的计时功能。Linux内核空间中的计时与用户空间的计时不太相同。在内核空间里,有一个全局变量Jiffies维护着当前的时间。与系统时钟有关的调用有(新的定时服务):

#include <asm/param.h> 
          
#include <linux/timer.h> 
          
void add_timer(struct timer_list * timer); 
          
int del_timer(struct timer_list * timer); 
          
inline void init_timer(struct timer_list * timer); 
          

 

结构struct timer_list的定义为:

struct timer_list { 
          
        struct timer_list *next; 
          
        struct timer_list *prev; 
          
        unsigned long expires; 
          
        unsigned long data; 
          
        void (*function)(unsigned long d); 
          
}; 
          

 

其中过期时间expires是要执行function的时间。一般在调用add_timer时jiffies = jiffies + num,表示在num个系统最小时间间隔后执行function。系统最小时间间隔与所用的硬件平台有关, 在核心里定义了常数HZ表示一秒内最小时间间隔的数目,则num*HZ表示num 秒。系统计时到预定时间就调用function,并把此子程序从定时队列里删除, 因此如果想要每隔一定时间间隔执行一次的话,就必须在function里再一次调用add_timer。function的参数d即为timer里面的data项。

Jiffies的计时精度是百分之一秒,如果在内核中需要更为精确的计时,就需要用到time_calls.h中的函数,它们可用于高精度的时间计算。

 


 

补充

有的时候,我们需要较为精确地得出被测目标的运行时间,这时一般需要多次运行取均值以消除误差。

gettimeofday( &start, NULL );
          
for ( int i = 0; i< 10; i++ ) foo(); 
          
gettimeofday( &end, NULL );
          
timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec; 
          
timeuse /= 10000000;
          

 

上面的统计实际也引入了新的误差,当循环指令的执行时间与foo()相比可忽略的话,这种计时才是可以接受的;否则我们就要除去循环指令的执行时间,才会得到正确的统计计时。

在Linux Shell下,如果统计次数较少,则可以:

for i in 1 2 3 4 5 6 7 8 9 10
          
do
          
        (time foo) 2>foo.tmp
          
        grep real foo.tmp | cut -f2 >> foo.txt
          
done
          

 

如果计时次数较多,则需要:

i=1
          
while [ $i -le 100 ]
          
do
          
        (time foo) 2>foo.tmp
          
        grep real foo.tmp | cut -f2 >> foo.txt
          
        i=`expr $i + 1`
          
done
          

 

写进foo.txt的内容如果手动来计算平均值,会比较费时,我们可以写一段Shell脚本或用C语言来读取文件,计算其均值。

/*耗时中分部总和*/
          
cut -d'm' -f1 foo.txt > foo.tmp
          
sum=0
          
while read line
          
do
          
        sum=$(echo "$sum+$line" | bc -l)
          
done < foo.tmp
          
echo $sum
          
/*耗时中秒部总和*/
          
cut -d'm' -f2 foo.txt | tr -d 's'> foo.tmp
          
sum=0
          
while read line
          
do
          
        sum=$(echo "$sum+$line" | bc -l)
          
done < foo.tmp
          
echo $sum
          

 

计算出分部与秒部总和之后,然后再手动计算平均值,这样要容易得多。注意,上面没有使用expr进行计算的原因,是因为expr只能支持整型值。在Linux shell下,如果要计算浮点数,就需要使用bc或者是gexpr。

 


 

结束语

实际上,我们还可以使用诸如Perl、Python等多种语言在Linux系统中进行计时。选择何种工具或语言进行计时,这与被测程序或程序段的类型以及它们的编写语言相关。综合考虑精度、运行时间、运行次数等要求,才能合理可靠地得出程序的运行时间。

 

 

c/c++编程中的计时功能

作者 wildpuma 23:06 | 链接 | 评论 (25) | 引用 (0) | c/c++编程

在linux下的c/c++编程中,计时有三种精度,秒(s)、毫秒(ms)、微秒(us),这三种方式的实现互不相同。主要是用clock(),times(),gettimeofday()三个函数来实现。三种数据结构好像是clock_t,stuct timeval等。

 

Linux基本操作(3) Linux基本指令的使用 阅读详情

相关推荐

Linux time 命令 -v 选项详解:从 15 项输出指标定位程序性能瓶颈

本文深入解析Linux time命令的-v选项,详细解读15项关键性能指标,帮助开发者精准定位程序性能瓶颈。通过分析内存使用、进程调度和I/O操作等核心指标,掌握如何识别CPU竞争、内存不足和I/O瓶颈等常见问题,提升性能调优效率。特别关注/usr/bin/time命令在real、user和sys时间分析之外的高级用法。

weixin_30765505的博客 508

Linux之date时间与timestamp时间戳转换

用的时候老忘,记录下: 转时间戳:date +%s 时间戳转时间:date -d @1626656829

Quincy.Coder的博客 1675

Linux编程:time/gettimeofday获取时间戳

时间戳:指格林威治时间从1970年1月1日(00:00:00 GMT)至当前时间的总秒数。2.通过gettimeofday。

风静如云的博客 1万+

Linux时间戳timestamp导致端口不通

Linux时间戳timestamp导致端口不通

doctorxusong的博客 2755

别再手动算频谱了!用这个在线FFT工具,5分钟搞定JSON/CSV数据分析

本文介绍了一款高效的在线FFT工具,帮助用户快速分析JSON/CSV格式的时域数据,5分钟内完成频谱分析。通过傅里叶变换(FFT)算法,大幅提升计算效率,解决传统手动计算的痛点,适用于工业振动分析、设备故障诊断等场景。

weixin_29172201的博客 261

告别系统迁移蓝屏!用Intel RST驱动搞定11代酷睿装Win11的硬盘识别难题

本文详细介绍了如何通过Intel RST驱动解决11代酷睿处理器在安装Win11时遇到的硬盘识别问题。针对VMD技术导致的系统迁移蓝屏错误,提供了从驱动下载、PE环境创建到驱动注入的完整解决方案,帮助用户顺利完成系统升级或迁移。

weixin_31309419的博客 577

ARM Linux RTC 时间的读取与设置

问题描述   RTC 芯片采用 PCF8563T,Linux 系统使用 date 设置时间后用 hwclock -w 同步到 RTC,一段时间后 Linux 系统时间与本地时间相差 8 个小时。 分析问题   直觉告诉我们这是时区造成的,要么是系统的时区配置不对,要么是 RTC 时间的读写不对。 时区配置主要是两个文件:/etc/localtime 和 /etc/timezone,内容...

程序员「阿基米东」的编程之旅 1万+

别再死磕U-Net了!用PyTorch手把手教你搭建ResUnet,搞定医学图像分割(附完整代码)

本文详细介绍了如何利用PyTorch搭建ResUnet模型,通过引入残差连接解决医学图像分割中的梯度消失、特征退化和细节丢失问题。与传统U-Net相比,ResUnet在Dice系数和收敛速度上均有显著提升,特别适合处理脑部MRI等复杂医学图像。文章还提供了完整的代码实现和关键训练技巧,帮助开发者快速掌握这一先进技术。

weixin_42552637的博客 327

Oracle与DST(daylight saving time)

是在看升级文档的时候注意到DST的这个概念,DST(daylight saving time)。 升级的时候为什么要更改DST呢? 因为oracle 数据库中有两个数据类型存储的数据都与DST相关,它们就是:TIMESTAMP WITH LOCAL TIME ZONE (TSLTZ) and TIMESTAMP WITH TIME ZONE (TSTZ) 还有一些工具也与此相关,但是不会直接

renfengjun 2903

Kaamel白皮书:IoT设备安全隐私评估实践

明确评估的目的和预期结果。

kaamelai的博客 1318

ESP32对接百度智能云语音识别:从硬件配置到API调用的完整指南

本文详细介绍了ESP32对接百度智能云语音识别的完整流程,从硬件配置到API调用,涵盖麦克风选择、音频处理、错误处理及性能优化等关键环节。通过实战案例展示如何实现低成本、高效率的语音交互方案,特别适合智能硬件开发者参考。

weixin_29198045的博客 375

The Passage of Time

Many features of the Linux kernel are critically dependent on the passage of time. The Linux kernel makes use of different timers provided by hardware to provide time-dependent services such as busy

小猪爱拱地 7706

电芯外观及体系设计(Cell Design)-①容量平衡设计(Cell Balance Design)

全面获取并正确解读客户需求,将需求进行分解和预判,结合公司现有资源、技术,给出设计方案。一个优秀的电芯设计方案,应该是稳健的,可操作的,满足客户需求的同时,并能为公司带来较多利润。电芯设计需同时考虑周期,性能,品质,加工性,成本,及安全与稳健性。设计人员时刻要有成本控制观念,但利润则是由公司战略所决定。

FDC1303864002的博客 1352

linux的tcp时间戳,TCP timestamp 相关知识

tcp_timestamps是在RFC 1323中定义的一个TCP选项。这篇wiki介绍一下timestamps的设计目的和相关原理,尤其强调一些比较tricky的地方。关于RFC1323这是一篇介绍针对High-bandwidth, Long delay链路设计的一些TCP扩展选项的资料。强烈推荐阅读!但这篇RFC其实已经被RFC7323所取代,不过RFC1323对于了解timestamp相关的...

weixin_30249997的博客 2073

基于阿里云物联网平台设计的实时图传系统_采用MQTT协议传输图像

当前基于MQTT协议设计了一个实时图传系统,通过这个项目来演示,两个MQTT设备如何互相订阅,进行消息流转。 在阿里云服务器上创建2个设备,分为为设备A和设备B;设备A负责采集本地摄像头画面上传,设备B负责接收设备A上传的数据然后解析显示出来。在阿里云服务器上需要配置云产品流转,让设备A的数据上传后自动发送给设备B。这样就完成了视频画面数据的流转。不过因为阿里云的最大数据限制,每次最大发送10240字节的数据。

1万+

基于YOLOv8的铁路轨道异物检测系统设计与实现

目标检测是计算机视觉领域的核心任务之一,旨在识别图像中特定目标的位置和类别。传统方法主要依赖手工特征(如HOG、SIFT等)和分类器(如SVM),而深度学习方法通过卷积神经网络自动学习特征表示,显著提升了检测性能。YOLO(You Only Look Once)系列算法作为单阶段目标检测的代表,以其高效的检测速度著称。YOLOv8是Ultralytics公司于2023年发布的最新版本,在精度和速度上都有进一步提升。

YOLO 574

Linux下时间相关

/* 与时间相关的定义所在的文件夹 /usr/include/time.h  /usr/include/bits/time.h struct timeval  {  time_t tv_sec;  susecond_t tv_usec; //当前妙内的微妙数  }; struct tm    {    int tm_sec; //当前秒     int tm_m

tooyoungtosimple的博客 388

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

mysql中datetime到time_t转换

http://blog.youkuaiyun.com/wxq1987525/article/details/6347228 FROM_UNIXTIME(time(NULL))将liunx系统的time_t类型时间,转换为mysql的datetime类型时间:: 在sql语句中用FROM_UNIXTIME(时间值); 将时间值,time_t类型转换成mysql的datetime类型。 cr

张同光 (Tongguang Zhang):Hello everyone ! 1016

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

ICMP Timestamp与Traceroute叠加风险:原理、复现与加固方案

ICMP(Internet控制报文协议)是TCP/IP协议簇的核心组件之一,主要用于在IP主机、路由器之间传递控制消息,例如网络通断诊断(ping)和路由错误报告。其Timestamp请求/响应机制设计初衷是进行简单时钟同步,但默认开启时会无差别响应请求,导致系统时间信息泄露。结合Traceroute工具利用TTL超时和目的不可达报文进行路径探测的特性,两者叠加形成了一种隐蔽的信息泄露风险,为攻击者提供了高质量的资产发现与网络侦察能力。这种风险并非传统高危漏洞,而是安全边界模糊地带,在纵深防御体系中需重点关

weixin_34234829的博客 485

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

linux 时间相关的命令

显示当前时间的 Unix 时间戳(秒级,从 1970-01-01 00:00:00 UTC 开始)

菜鸡搞计算机 627

java通过mybatis设置TimeStamp字段的问题排查

部门小伙伴报在生产环境下,spring通过mybatis方式设置CreateTime字段,数据库中显示的时候不正确,倒退了13个小时。但是在测试环境是OK的。 排查过程 1. 代码 首先排查了代码的写法。 r.setCreateTime(new Date()); ...

chitaicuo6854的博客 1656

快速回收复用TCP的TIME_WAIT

最近同事遇到一个问题,使用python开发的工具在执行的时候无法和MySQL建立连接,其最直接的现象就是满篇的TIME_WAIT,最后通过调整tcp_timestamps参数问题得以解决,再次记录一下这次解决的经验总结。 ps:不过先汗颜一个,对基础的tcp知识太不敏感了,需要回炉重新学习啊。 一、看下TIME_WAIT产生的原因 大家都知道建立连接是著名的三次握手机制。   那么如何关

汪迎春的专栏 6005

linux内核协议栈TCP time_wait原理、配置、副作用

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33971130的博客 290

mysql时间戳查询_mysql查询时间戳(TIMESTAMP)

在mysql数据中查询的时间戳1.普通时间转unix/linux时间戳命令unix_timestamp()是时间函数mysql> select unix_timestamp(20131001);时间格式: YYYY-MM-DD HH:MM:SS 或 YYMMDD 或 YYYYMMDD+--------------------------+| unix_timestamp(20131001)...

weixin_35802571的博客 6443

TCP/IP协议栈中的TimeStamp选项

TCP应该是以太网协议族中被应用最为广泛的协议之一,这里就聊一聊TCP协议中的TimeStamp选项。这个选项是由RFC 1323引入的,该C建议提交于1992年,到今天已经足足有20个年头。不过相信大部分程序猿对这个建议还是相当陌生。要理解为啥需要用TimeStamp选项,还需要从TCP协议的几个基本设计说起。 TCP协议的几个设计初衷,以及引发的问题:1. 协议规定收端不需要响应每一个收到的...

weixin_30515513的博客 1279

mysql连接 为什么不能复用_解决MySQL建立连接问题,快速回收复用TCP的TIME_WAIT

最近同事遇到一个问题,使用python开发的工具在执行的时候无法和MySQL建立连接,其最直接的现象就是满篇的TIME_WAIT,最后通过调整tcp_timestamps参数问题得以解决,再次记录一下这次解决的经验总结。ps:不过先汗颜一个,对基础的tcp知识太不敏感了,需要回炉重新学习啊。一、看下TIME_WAIT产生的原因大家都知道建立连接是著名的三次握手机制。那么如何关闭连接呢? 其实也是著...

weixin_36316291的博客 511
上一篇: 关于shared library的描述。
下一篇: IEEE与通信协议的定义。
testhw
博客等级 码龄19年 172粉丝 183原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值