一尘不染

Linux上进程的开始时间

linux

如何使用C语言在ubuntu linux机器上查找进程开始时间。在linux中,/ proc / [pid] / stat文件提供信息

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为单位。


阅读 282

收藏
2020-06-07

共1个答案

一尘不染

当人们编译Linux内核时,每秒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() */
2020-06-07