`
weihe6666
  • 浏览: 444834 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论
阅读更多
Linux-time


下面是引用别人的blog:
用途说明
time命令常用于测量一个命令的运行时间,注意不是用来显示和修改系统时间的(这是date命令干的事情)。但是今天我通过查看time命令的手册页,发现它能做的不仅仅是测量运行时间,还可以测量内存、I/O等的使用情况,手册页上的说法是time a simple command or give resource usage,其中time一词我认为它应该是测量或测定的意思,并不单指时间。一个程序在运行时使用的系统资源通常包括CPU、Memory和I/O等,其中CPU资源的统计包括实际使用时间(real time)、用户态使用时间(the process spent in user mode)、内核态使用时间(the process spent in kernel mode)。但是简单的使用time命令并不能得到内存和I/O的统计数据,请看后文慢慢道来。

常用参数
time命令最常用的使用方式就是在其后面直接跟上命令和参数:

time <command> [<arguments...>]

在命令执行完成之后就会打印出CPU的使用情况:

real    0m5.064s      <== 实际使用时间(real time)
user    0m0.020s     <== 用户态使用时间(the process spent in user mode)
sys     0m0.040s      <== 内核态使用时间(the process spent in kernel mode)

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

使用示例
示例一 统计运行时间
[root@web186 root]# time find . -name "mysql.sh"
./work186/sms/bin/mysql.sh
./work186/sms/src/scripts/mysql.sh
./work186/sms/src/scripts1/mysql.sh
./work186/sms1/bin/mysql.sh
./work186/sms1/src/scripts/mysql.sh
./temp/sms/bin/mysql.sh
./temp/sms/src/scripts/mysql.sh

real    0m14.837s
user    0m0.030s
sys     0m0.120s

示例三 解决time命令输出信息的重定向问题
time命令的输出信息是打印在标准错误输出上的, 我们通过一个简单的尝试来验证一下。

[root@web186 root]# time find . -name "mysql.sh" >1.txt

real    0m0.081s
user    0m0.060s
sys     0m0.020s
[root@web186 root]# time find . -name "mysql.sh" 2>2.txt
./work186/sms/bin/mysql.sh
./work186/sms/src/scripts/mysql.sh
./work186/sms/src/scripts1/mysql.sh
./work186/sms1/bin/mysql.sh
./work186/sms1/src/scripts/mysql.sh
./temp/sms/bin/mysql.sh
./temp/sms/src/scripts/mysql.sh

real    0m0.068s
user    0m0.040s
sys     0m0.030s

通过上面的尝试,发现无法将time的输出信息重定向到文件里面,为什么?因为time是shell的关键字,shell做了特殊处理,它会把time命令后面的命令行作为一个整体来进行处理,在重定向时,实际上是针对后面的命令来的,time命令本身的输出并不会被重定向的。那现在怎么办呢?网上提供了两种解决方法【2,3】,我们一一尝试一下。

第一种解决方法,就是将time命令和将要执行的命令行放到一个shell代码块中,也就是一对大括号中,要注意空格和分号的使用。
[root@web186 root]# {time find . -name "mysql.sh"} 2>2.txt

好像成功了。慢,看一下对不对。
[root@web186 root]# cat 2.txt
-bash: {time: command not found

原来bash把 {time 作为一个整体来处理了,前后都加上空格试试。
[root@web186 root]# { time find . -name "mysql.sh" } 2>2.txt
> Ctrl+C

这次Bash认为命令都没有输入完成,少了分号。因为Bash认为后面的 } 是find命令的参数。
[root@web186 root]# { time find . -name "mysql.sh"; } 2>2.txt
./work186/sms/bin/mysql.sh
./work186/sms/src/scripts/mysql.sh
./work186/sms/src/scripts1/mysql.sh
./work186/sms1/bin/mysql.sh
./work186/sms1/src/scripts/mysql.sh
./temp/sms/bin/mysql.sh
./temp/sms/src/scripts/mysql.sh
[root@web186 root]# cat 2.txt

real    0m0.068s
user    0m0.030s
sys     0m0.040s

第一种方式的尝试成功了,总结起来就是 { time command-line; } 2>file  注意分隔符的使用。

另外一种方式就是使用子Shell的方式,如下所示:

[root@web186 root]# (time find . -name "mysql.sh") 2>2.txt
./work186/sms/bin/mysql.sh
./work186/sms/src/scripts/mysql.sh
./work186/sms/src/scripts1/mysql.sh
./work186/sms1/bin/mysql.sh
./work186/sms1/src/scripts/mysql.sh
./temp/sms/bin/mysql.sh
./temp/sms/src/scripts/mysql.sh
[root@web186 root]# cat 2.txt

real    0m0.083s
user    0m0.040s
sys     0m0.020s
[root@web186 root]#

第二种方式的尝试也成功了,总结起来就是 (time command-line) 2>file 这里time紧贴着小括号(也可以的,命令行结束也不必带分号。当然最好还是用第一种方式,毕竟启动一个子shell是要多占些资源的。


Linux中time命令,我们经常用来计算某个程序的运行耗时,用户态cpu耗时,系统态cpu耗时。

例如:

$ time foo real        0m0.003suser        0m0.000ssys         0m0.004s$那么这三个时间都具体代表什么意思呢?

[1] real : 表示foo程序整个的运行耗时,可以理解为foo运行开始时刻你看了一下手表,foo运行结束时,你又看了一下手表,两次时间的差值就是本次real 代表的值

举个极端的例子如下:可以看到real time恰好为2秒。

# time sleep 2

real    0m2.003s

user    0m0.000s

sys     0m0.000s

[2] user   0m0.000s:这个时间代表的是foo运行在用户态的cpu时间,什么意思?

首先,我来讲一下用户态和核心态:

核心态(Kernel Mode):

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

       —– In Kernel mode, the executing code has complete and unrestricted access to the underlying hardware. It can execute any CPU instruction and reference any memory address. Kernel mode is generally reserved for the lowest-level, most trusted functions of the operating system. Crashes in kernel mode are catastrophic; they will halt the entire PC.

用户态(User Mode):

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

      —– In User mode, the executing code has no ability to directly access hardware or reference memory. Code running in user mode must delegate to system APIs to access hardware or memory. Due to the protection afforded by this sort of isolation, crashes in user mode are always recoverable. Most of the code running on your computer will execute in user mode.

为什么要区分Kernel Mode 和 User Mode:

     隔离保护,使得系统更稳定。

好,讲完用户态和核心态之后,我们来看user time,说过了,这个指的是程序foo运行在用户态的cpu时间,cpu时间不是墙上的钟走过的时间,而是指CPU工作时间。

[3] sys   0m0.004s : 这个时间代表的是foo运行在核心态的cpu时间。



好,讲完上面的这些,我们来看看这三个的关系,这三者之间没有严格的关系,常见的误区有:

误区一: real_time = user_time + sys_time

       我们错误的理解为,real time 就等于 user time + sys time,这是不对的,real time是时钟走过的时间,user time 是程序在用户态的cpu时间,sys time 为程序在核心态的cpu时间。

利用这三者,我们可以计算程序运行期间的cpu利用率如下:

%cpu_usage = (user_time + sys_time)/real_time * 100%

如:

# time sleep 2

real     0m2.003s

user    0m0.000s

sys     0m0.000s

cpu利用率为0,因为本身就是这样的,sleep 了2秒,时钟走过了2秒,但是cpu时间都为0,所以利用率为0

误区二:real_time > user_time + sys_time

一般来说,上面是成立的,上面的情况在单cpu的情况下,往往都是对的。

但是在多核cpu情况下,而且代码写的确实很漂亮,能把多核cpu都利用起来,那么这时候上面的关系就不成立了,例如可能出现下面的情况,请不要惊奇。

real 1m47.363s

user 2m41.318s

sys 0m4.013s

分享到:
评论

相关推荐

    linux-time.rar_LINUX TIME _Time

    `linux-time.rar`这个压缩包似乎包含了关于Linux时间API实现的相关源代码,主要文件是`linux-time.c`。这里我们将深入探讨Linux时间API的实现、相关概念以及它们在用户级和内核级的应用。 1. **Linux时间API**: ...

    linux-time.rar_Time

    "linux-time.rar_Time"这个压缩包可能包含了关于Linux内核和用户空间中时间API实现的详细代码和文档,其中"linux-time.c"是源代码文件。下面将详细讨论Linux时间API的重要性和其主要功能。 1. **时间API的重要性** ...

    NI CompactRIO支持最新的 Linux Real-Time实时操作系统,满足您的嵌入式应用需求.zip

    NI CompactRIO是一款高度灵活且强大的嵌入式控制系统,它采用了最新的Linux Real-Time实时操作系统,为各种复杂的应用场景提供了高效且可靠的解决方案。Linux Real-Time是一种经过优化的Linux版本,特别针对实时性能...

    util-linux-ng-2.17源码(含fdisk)

    util-linux-ng-2.17源码(含fdisk) Here is a list of all documented files with brief descriptions: util-linux-ng-2.17.2/disk-utils/blockdev.c [code] util-linux-ng-2.17.2/disk-utils/cramfs.h [code] ...

    arm-linux-gcc交叉编译器 4.3.2 part2

    arm-linux-gcc交叉编译器,版本4.3.2,用于Linux下的ARM开发。 本文件为arm-linux-gcc-4.3.2.tgz的part2 arm-linux-gcc-4.3.2.tgz.ab,需要与arm-linux-gcc-4.3.2.tgz的part1 arm-linux-gcc-4.3.2.tgz.aa 合并成一个......

    jdk-8u341-linux-x64安装包

    - **特性**:此版本引入了Lambda表达式、函数式编程、新的日期时间API(java.time)、Stream API等重大改进,提高了代码的简洁性和性能。 4. **Linux x64**: 这里的“x64”意味着这两个安装包都是为64位(AMD64...

    jdk-8u181-linux-x64.tar.gz

    Java 8是Oracle公司发布的一个重要版本,引入了许多新特性,如Lambda表达式、函数式编程、Stream API、Date和Time API的改进以及默认方法等。这些特性极大地增强了Java语言的简洁性和效率,使其更适合现代软件开发的...

    jdk-8u181-linux-x64-x86.rpm

    Java 1.8是一个重要的Java版本,它引入了许多新的特性和改进,比如Lambda表达式、函数式编程支持、Stream API、Date和Time API的改进以及更好的并发处理。 在文件名称列表中提到了"jdk-8u181-linux-x64.rpm",这是...

    kubernetes-node-linux-amd64.tar.gz

    --runtime-request-timeout=15m \\ --kubeconfig=/var/lib/kubelet/kubeconfig \\ --allow-privileged=true \\ --network-plugin=cni \\ --cni-conf-dir=/etc/cni/net.d \\ --cni-bin-dir=/opt/cni/bin \\ --...

    linux-timemachine:用于Linux,MacOS和BSD的基于Rsync的类似于OSX的时间机器,用于原子和可恢复的本地和远程备份

    Linux Time Machine | | | | | | | timemachine是一个微小且稳定的KISS驱动且符合POSIX的脚本,模仿了OSX的timemachine行为。 它使用rsync通过SSH将数据增量备份到其他目录,硬盘或远程服务器。 所有操作都是增量...

    jdk-8u91-linux-x64.tar.gz

    - Date和Time API的改进:提供了一套新的日期和时间API,使得处理日期和时间更加方便和精确。 - Type接口:允许泛型擦除后的类型信息在运行时可获取。 7. **使用场景**: - 开发Java桌面应用、Web应用、移动应用...

    clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz

    LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容...

    最新版linux jdk-8u251-linux-x64.tar.gz

    - **日期时间API**:`java.time`包替换旧的`java.util.Date`和`java.util.Calendar`,提供了更强大的日期和时间处理功能。 5. **安全与维护**: 保持JDK的更新对于安全性和稳定性至关重要。定期检查Oracle官网的...

    jdk-8u191-linux-x64.tar.gz

    标题 "jdk-8u191-linux-x64.tar.gz" 指的是Java Development Kit (JDK) 的一个特定版本,适用于64位的Linux操作系统。这个版本是8u191,其中"8"代表JDK的第8个主要版本,"u191"则表示该版本是第191次更新。JDK是Java...

    jdk-8u11-linux-x64.tar.gz

    4. **日期和时间API的改进**:Java 8引入了新的java.time包,取代了过时的java.util.Date和java.util.Calendar,提供了更强大、更易用的日期和时间处理功能。 5. **默认方法**:接口现在可以包含默认方法实现,这...

    jdk-8u311-linux-x64.tar.zip

    这个版本在Java历史上占有重要地位,引入了许多新特性,如Lambda表达式、Stream API、默认方法以及改进的Date/Time API等。 对于JDK 8u311,它是Java 8的更新版本,通常包含性能优化、安全修复和bug修复。这些更新...

    jdk-8u311-linux-x64.tar.gz.7z

    JDK 8是Java的一个重要里程碑,引入了许多新的特性和改进,例如Lambda表达式、Stream API、新的Date和Time API、默认方法等。这些特性极大地提升了代码的简洁性和可读性,同时提高了开发效率。对于Java开发者来说,...

    jdk-8u6-linux-arm-vfp-hflt.tar.zip

    JDK 8引入了许多重要的特性,例如Lambda表达式,用于简化多线程编程的Fork/Join框架,以及改进的Date和Time API。对于开发人员来说,理解这些特性并能熟练运用它们是至关重要的。 总结,"jdk-8u6-linux-arm-vfp-...

    jdk-8u381-linux-x64

    以及Date/Time API的改进,提供更好的日期和时间处理功能。 在维护和升级方面,定期更新到最新版本的JDK是非常重要的,因为这不仅可以获取新的特性和性能优化,还能确保系统免受已知安全漏洞的威胁。"jdk-8u381-...

    jdk-8u231-linux-x64_tar_gz.zip

    JDK 8的亮点包括Lambda表达式、方法引用、Stream API、默认方法(接口中的实现)以及新的Date和Time API等。这些特性极大地提高了Java的开发效率和代码可读性。同时,JDK 8还引入了新的并发工具类,如Fork/Join框架...

Global site tag (gtag.js) - Google Analytics