2011-04-29 82 views
3

如何在使用c语言的ubuntu linux机器上查找进程启动时间。在linux下有的/ proc/[PID]/STAT文件,该文件提供信息Linux上的进程启动时间

starttime %lu /*The time in jiffies the process started after system boot*/
和文件/ proc/STAT,让

btime %lu /*measurement of system boot time since Epoch in seconds*/ 

对于加入这两个值我如何转换前值成秒,因为它在jiffies单位。

+1

见http://stackoverflow.com/questions/2731463/converting-jiffies-to-milli-seconds – Erik 2011-04-29 06:40:26

+0

@Erik是啊,这帖子是巨大的。是否有另一种方法来计算过程创建时间。 – 2011-04-29 06:49:15

回答

4

当编译Linux内核时,每秒Jiffies是可配置的。

以下程序使用您正在运行的内核每秒的jiffies数量。它需要一个可选的命令行参数,它是进程号。缺省值是正在运行的程序本身的进程号。每秒输出指定进程的开始时间,包括本地时间和UTC。重复循环的唯一原因是证明该值不会改变。

#include <sys/stat.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 
#include <unistd.h> 
int 
find_nth_space(char *search_buffer, 
       int space_ordinality 
      ) 
{ 
    int jndex; 
    int space_count; 

    space_count=0; 

    for(jndex=0; 
     search_buffer[jndex]; 
     jndex++ 
    ) 
    { 
    if(search_buffer[jndex]==' ') 
    { 
     space_count++; 

     if(space_count>=space_ordinality) 
     { 
     return jndex; 
     } 
    } 
    } 

    fprintf(stderr,"looking for too many spaces\n"); 

    exit(1); 

} /* find_nth_space() */ 

int 
main(int argc, 
    char **argv 
    ) 
{ 
    int  field_begin; 
    int  stat_fd; 

    char  proc_buf[80]; 
    char  stat_buf[2048]; 

    long  jiffies_per_second; 

    long long boot_time_since_epoch; 
    long long process_start_time_since_boot; 

    time_t process_start_time_since_epoch; 

    ssize_t read_result; 

    struct tm gm_buf; 
    struct tm local_buf; 

    jiffies_per_second=sysconf(_SC_CLK_TCK); 

    if(argc<2) 
    { 
    strcpy(proc_buf,"/proc/self/stat"); 
    } 
    else 
    { 
    sprintf(proc_buf,"/proc/%ld/stat",strtol(argv[1],NULL,0)); 
    } 

    for(;;) 
    { 
    stat_fd=open(proc_buf,O_RDONLY); 

    if(stat_fd<0) 
    { 
     fprintf(stderr,"open() fail\n"); 

     exit(1); 
    } 

    read_result=read(stat_fd,stat_buf,sizeof(stat_buf)); 

    if(read_result<0) 
    { 
     fprintf(stderr,"read() fail\n"); 

     exit(1); 
    } 

    if(read_result>=sizeof(stat_buf)) 
    { 
     fprintf(stderr,"stat_buf is too small\n"); 

     exit(1); 
    } 

    field_begin=find_nth_space(stat_buf,21)+1; 

    stat_buf[find_nth_space(stat_buf,22)]=0; 

    sscanf(stat_buf+field_begin,"%llu",&process_start_time_since_boot); 

    close(stat_fd); 

    stat_fd=open("/proc/stat",O_RDONLY); 

    if(stat_fd<0) 
    { 
     fprintf(stderr,"open() fail\n"); 

     exit(1); 
    } 

    read_result=read(stat_fd,stat_buf,sizeof(stat_buf)); 

    if(read_result<0) 
    { 
     fprintf(stderr,"read() fail\n"); 

     exit(1); 
    } 

    if(read_result>=sizeof(stat_buf)) 
    { 
     fprintf(stderr,"stat_buf is too small\n"); 

     exit(1); 
    } 

    close(stat_fd); 

    field_begin=strstr(stat_buf,"btime ")-stat_buf+6; 

    sscanf(stat_buf+field_begin,"%llu",&boot_time_since_epoch); 

    process_start_time_since_epoch 
    = 
    boot_time_since_epoch+process_start_time_since_boot/jiffies_per_second; 

    localtime_r(&process_start_time_since_epoch,&local_buf); 
    gmtime_r (&process_start_time_since_epoch,&gm_buf ); 

    printf("local time: %02d:%02d:%02d\n", 
      local_buf.tm_hour, 
      local_buf.tm_min, 
      local_buf.tm_sec 
     ); 

    printf("UTC:  %02d:%02d:%02d\n", 
      gm_buf.tm_hour, 
      gm_buf.tm_min, 
      gm_buf.tm_sec 
     ); 

    sleep(1); 
    } 

    return 0; 
} /* main() */ 
+0

埃文斯非常感谢! – 2011-04-30 04:26:23