一个程序的执行时间可以使用time+命令形式来获得

编写程序testtime.c

#include <stdio.h>   //这个头一定要加
#include<time.h>
main()
{
 time_t timep;
 time (&timep);
 printf("%s",ctime(&timep)); 
}

前提已安装gcc

[root@fp-mysql-4 src]# rpm -qa | grep gcc
libgcc-4.4.7-3.el6.x86_64

[root@fp-web-112 linuxtime]# yum install gcc
编译&测试
//编译
[root@fp-web-112 linuxtime]# gcc -o  testtime testtime.c -lpthread
[root@fp-web-112 linuxtime]# chmod 777 testtime
//查看程序执行时间
[root@fp-mysql-4 src]# time ./testtime
首先输出main
thd2: this is thd2
thd1: this is thd1
thd2: this is thd2
首先输出main
thd1: this is thd1
thd2: this is thd2
thd1: this is thd1
首先输出main
^C
real    0m2.362s  //实际运行时间
user    0m0.001s  //用户态时间
sys    0m0.000s   //内核态时间

 

这里说一下输出的real 、 user、sys三个时间

在运行的程序之前加 time 最后得出三个时间 real、  user、 sys。

 real是程序的实际运行时间,sys是内核态的时间,user是用户态的时间,单核情况,real远远大于user和sys之和。

1、real从程序开始到程序执行结束时所消耗的时间,包括CPU的用时和所有延迟程序执行的因素的总和。
  CPU用时被划分为user和sys两块。
  user表示程序本身,以及它所调用的库中的子例程使用的时间。
  sys是由程序直接或间接调用的系统调用执行的时间.

  real=cpu用时(user+sys)+其他因素时间

  所以: real> user + sys (单核情况)

  time命令结果有三行组成:real、user和sys。CPU用时被划分为user和sys两块。

  real值表示从程序开始到程序执行结束时所消耗的时间,包括CPU的用时

2、user值表示程序本身,以及它所调用的库中的子例程使用的时间

在user用户态,代码不具备直接访问硬件或者访问内存的能力,而必须借助操作系统提供的可靠的,底层的APIs来访问硬件或者内存。
由于这种隔离带来的保护作用,用户态的代码崩溃(Crash),系统是可以恢复的。我们大多数的代码都是运行在用户态的。

3、sys是由程序直接或间接调用的系统调用执行的时间(系统调用这个可以百度一下,就是用户程序或者说自己写的程序,调用内核开放给我们的接口比如:函数等,可提供给我们的

在内核态,代码拥有完全的,不受任何限制的访问底层硬件的能力。可以执行任意的CPU指令,访问任意的内存地址。
内核态通常情况下,都是为那些最底层的,由操作系统提供的,可信可靠的代码来运行的。
内核态的代码崩溃将是灾难性的,它会影响到整个系统。


关于系统调用,即sys有关的,如果谁想开发底层的应用,可以参考官方

  https://www.kernel.org/doc/html/latest/process/howto.html

  https://www.kernel.org/doc/html/latest/process/adding-syscalls.html  //如何增加一个系统调用,在内核里面。

  https://man7.org/linux/man-pages/man2/syscall.2.html#NOTES

 

time命令跟上-p参数可以只打印时间数值(秒数),不打印单位

[root@fp-mysql-4 src]# time -p ./outgetpid 
首先输出main
thd1: this is  thd1
thd2: this is  thd2
thd2: this is  thd2
首先输出main
thd1: this is  thd1
thd2: this is  thd2
thd1: this is  thd1
首先输出main
real 2.39
user 0.00
sys 0.00

解释(1):real远大于user加上sys,因为find需要遍历各个目录,需要大量的I/O操作,
    而磁盘I/O通常是最慢的环节,因此大部分时间find进程都在等待磁盘I/O完成。

解释(2):再次运行的时候,发现real time变得很小了,应该是操作系统将刚才操作过的一些文件缓存了的缘故,
      因而大大减少了磁盘I/O。使用-p参数时,直接打印所需时间的数值,单位为秒。

 

查看进程运行在那颗cpu上,看是否在轮询cpu



利用命令: ps
-o pid,psr,comm -p <pid>
//启动一个一直执行的程序
[root@fp-mysql-4 src]# time -p ./outgetpid
//另一个中断查看 
[root@ht8 ~]# ps -ef | grep out

  95434

//psr就是运行在哪个cpu上的标记.

[root@ht8 ~]# ps -o pid,psr,comm -p 95434
PID PSR COMMAND
95434 0 time

PSR 列会根据内核可能调度该进程到不同CPU而改变显示。

//我用的两个终端来看演示过程

[root@ht8 ~]# ps -o pid,psr,comm -p 95434
PID PSR COMMAND
[root@ht8 ~]# ps -ef | grep out

 

查看time帮助, time其实是一个Shell程序.

[root@ht8 src]# help time
time: time [-p] pipeline
    Report time consumed by pipeline's execution.
    Execute PIPELINE and print a summary of the real time, user CPU time,
    and system CPU time spent executing PIPELINE when it terminates.
    Options:
      -p    print the timing summary in the portable Posix format
    The value of the TIMEFORMAT variable is used as the output format.
    Exit Status:
    The return status is the return status of PIPELINE.
times: times
    Display process times.
    Prints the accumulated user and system times for the shell and all of its
    child processes.
    Exit Status:
    Always succeeds.

我们用type -a 来看看time命令

[root@fp-mysql-4 src]# type -a time
time is a shell keyword

 

采样centos6和centos7

centos6 默认没有该命令
[root@fp-mysql-4 src]# /usr/bin/time -bash: /usr/bin/time: No such file or directory
centos7 默认支持

[root@ht8 src]# time ./outgetpid
首先输出main
thd1: this is thd1
thd2: this is thd2
thd1: this is thd1
thd2: this is thd2
首先输出main
thd1: this is thd1
thd2: this is thd2
首先输出main
thd2: this is thd2
thd1: this is thd1
首先输出main
real 0m3.261s
user 0m0.000s
sys 0m0.001s

[root@ht8 src]# /usr/bin/time ./outgetpid
首先输出main
thd1: this is thd1
thd2: this is thd2
thd1: this is thd1
首先输出main
thd2: this is thd2
thd2: this is thd2
首先输出main
thd1: this is thd1
0.00 user 0.00 system 0:02.06 elapsed 0%CPU (0 avgtext+0 avgdata 596 maxresident)k
0 inputs + 0 outputs (0 major + 190 minor) pagefaults 0 swaps

我们看到两个命令之间输出有差异,我对上面的输出进行了处理

我在看看另一个命令/usr/bin/time,它和time命令有何不同呢? 
利用/usr/bin/time -v 命令你会得到更多有用的信息。

[root@ht8 src]# /usr/bin/time -v ./outgetpid 
首先输出main
thd1: this is  thd1
thd2: this is  thd2
首先输出main
thd1: this is  thd1
thd2: this is  thd2
Command terminated by signal 2
    Command being timed: "./outgetpid"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 0%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.61
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 600
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 191
    Voluntary context switches: 7
    Involuntary context switches: 1
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096  //操作系统页大小
    Exit status: 0

操作系统页大小也可以通过

[root@ht8 src]# getconf PAGE_SIZE
4096  //4096/1024=4K大小

 

 

总结一下在linux中存在两个time程序:

 一个是bash的命令是一个shell程序,另外一个是程序/usr/bin/time。

time命令显示程序执行的时间,而/usr/bin/time程序可以显示很详细的与IO相关的数据,
比如从内存中读取了多少数据,从磁盘中读取了多少数据之类的,以及文件系统的页大小

posted @ 2022-03-09 14:11  jinzi  阅读(288)  评论(0编辑  收藏  举报