在已经运行的进程上输出time命令

时间:2014-05-04 13:02:01

标签: linux bash time

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

这可能吗?如何?

1 个答案:

答案 0 :(得分:4)

  

我想在特定进程上使用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),您无法为任意进程调用它。

所以,我不知道任何能提供相同输出的命令。但是,创建一个获取特定进程的PID并输出类似time outpus然后

的bash脚本是可行的。

此脚本执行以下步骤:

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:($ SYS_TIME /(getconf CLK_TCK))* 10 - 以毫秒为单位

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

这是我time的实现:

#!/bin/sh

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