【问题标题】:time command output on an already running process已运行进程的时间命令输出
【发布时间】:2014-05-04 13:02:01
【问题描述】:

我有一个进程会产生一些其他进程, 我想在特定进程上使用time 命令并获得与time 命令相同的输出。

这可能吗?如何实现?

【问题讨论】:

  • 如果您“在特定进程上使用time 命令”,您不会根据定义“获得与time 命令相同的输出”吗?
  • 不是吗?肯定不是它的用户时间。

标签: linux bash time


【解决方案1】:

我想在特定进程上使用 time 命令并获得与 time 命令相同的输出。

可能只使用pidstat 来获取用户和系统时间就足够了:

$ pidstat -p 30122 1 4
Linux 2.6.32-431.el6.x86_64 (hostname)        05/15/2014      _x86_64_        (8 CPU)

04:42:28 PM       PID    %usr %system  %guest    %CPU   CPU  Command
04:42:29 PM     30122  706.00   16.00    0.00  722.00     3  has_serverd
04:42:30 PM     30122  714.00   12.00    0.00  726.00     3  has_serverd
04:42:31 PM     30122  714.00   14.00    0.00  728.00     3  has_serverd
04:42:32 PM     30122  708.00   16.00    0.00  724.00     3  has_serverd
Average:        30122  710.50   14.50    0.00  725.00     -  has_serverd

如果不是,则根据 strace time 使用 wait4 系统调用 (http://linux.die.net/man/2/wait4) 从内核获取有关进程的信息。相同的信息返回 getrusage,但您不能根据其文档 (http://linux.die.net/man/2/getrusage) 为任意进程调用它。

所以,我不知道任何可以提供相同输出的命令。但是,创建一个 bash 脚本来获取特定进程的 PID 并输出类似 time outpus 的内容是可行的

此脚本执行以下步骤:

1) 获取每秒时钟滴答数

getconf CLK_TCK

我假设它是 100 并且 1 滴答等于 10 毫秒。

2) 然后在目录/proc/YOUR-PID存在的情况下循环执行相同的命令序列:

while [ -e "/proc/YOUR-PID" ];
do
  read USER_TIME SYS_TIME REAL_TIME <<< $(cat /proc/PID/stat | awk '{print $14, $15,  $22;}')
  sleep 0.1
end loop

一些解释-根据man proc

user time: ($14) - utime - Amount of time that this process has been scheduled in user mode, measured in clock ticks
sys time: ($15) - stime - Amount of time that this process has been scheduled in kernel mode, measured in clock ticks
starttime ($22) - The time in jiffies the process started after system boot.

3) 当进程完成时获取完成时间

   read FINISH_TIME <<< $(cat '/proc/self/stat' | awk '{print $22;}') 

然后输出:

  • 实际时间 = ($FINISH_TIME-$REAL_TIME) * 10 - 以毫秒为单位
  • 用户时间:($USER_TIME/(getconf CLK_TCK)) * 10 - 以毫秒为单位
  • 系统时间:($SYS_TIME/(getconf CLK_TCK)) * 10 - 以毫秒为单位

我认为它应该给出与时间大致相同的结果。我看到的一个可能的问题是该过程是否存在很短的时间。

这是我对time的实现:

#!/bin/bash
# Uses herestrings

print_res_jeffies()
{
  let "TIME_M=$2/60000"
  let "TIME_S=($2-$TIME_M*60000)/1000"
  let "TIME_MS=$2-$TIME_M*60000-$TIME_S*1000"
  printf "%s\t%dm%d.%03dms\n" $1 $TIME_M $TIME_S $TIME_MS
}

print_res_ticks()
{
  let "TIME_M=$2/6000"
  let "TIME_S=($2-$TIME_M*6000)/100"
  let "TIME_MS=($2-$TIME_M*6000-$TIME_S*100)*10"
  printf "%s\t%dm%d.%03dms\n" $1 $TIME_M $TIME_S $TIME_MS
}

if [ $(getconf CLK_TCK) != 100 ]; then
  exit 1;
fi

if [ $# != 1 ]; then
  exit 1;
fi

PROC_DIR="/proc/"$1

if [ ! -e $PROC_DIR ]; then
  exit 1
fi

USER_TIME=0
SYS_TIME=0
START_TIME=0

while [ -e $PROC_DIR ]; do
  read TMP_USER_TIME TMP_SYS_TIME TMP_START_TIME <<< $(cat $PROC_DIR/stat | awk '{print $14, $15,  $22;}')
  if [ -e $PROC_DIR ]; then
    USER_TIME=$TMP_USER_TIME
    SYS_TIME=$TMP_SYS_TIME
    START_TIME=$TMP_START_TIME
    sleep 0.1
  else
    break
  fi
done

read FINISH_TIME <<< $(cat '/proc/self/stat' | awk '{print $22;}')
let "REAL_TIME=($FINISH_TIME - $START_TIME)*10"
print_res_jeffies  'real' $REAL_TIME
print_res_ticks    'user' $USER_TIME
print_res_ticks    'sys' $SYS_TIME

这是一个比较我的time 和真实time 实现的示例:

>time ./sys_intensive > /dev/null
Alarm clock

real    0m10.004s
user    0m9.883s
sys     0m0.034s

在另一个终端窗口中,我运行 my_time.sh 并为其指定 PID:

>./my_time.sh `pidof sys_intensive`
real    0m10.010ms
user    0m9.780ms
sys     0m0.030ms

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 2018-09-12
    • 2011-05-21
    • 2014-10-27
    • 1970-01-01
    相关资源
    最近更新 更多