你怎么知道一个进程运行了多长时间?

时间:2011-06-28 23:56:30

标签: c++ c linux process-management

有没有办法从/proc目录中获取此信息?我希望能够在几秒钟内获得每个进程运行的时间。

编辑:我需要从C ++开始。对不起,感到困惑。

6 个答案:

答案 0 :(得分:6)

好的,所以在阅读top命令的源代码之后,我想出了一种获取进程开始时间的非hacky方法。他们使用的公式是:

Process_Time = (current_time - boot_time) - (process_start_time)/HZ.

(你必须除以HZ因为process_start_time是jiffies)

获取这些值:

  • current_time - 您可以从C命令gettimeofday()获取此信息。
  • boot_time - 此值位于/proc/uptime。此文件包含两个数字:系统的正常运行时间(秒)以及空闲进程所花费的时间(秒)。拿第一个。
  • process_start_time - 此值位于/proc/[PID]/stat。系统启动和进程启动时的时差(以jiffies为单位)。 (如果在空格上拆分,则为文件中的第22个值)。

代码(对不起,我有时混合使用c和c ++):

  int fd;
  char buff[128];
  char *p;
  unsigned long uptime;
  struct timeval tv;
  static time_t boottime;


  if ((fd = open("/proc/uptime", 0)) != -1)
  {
    if (read(fd, buff, sizeof(buff)) > 0)
    {
      uptime = strtoul(buff, &p, 10);
      gettimeofday(&tv, 0);
      boottime = tv.tv_sec - uptime;

    }
    close(fd);
  }


ifstream procFile;
procFile.open("/proc/[INSERT PID HERE]/stat");

char str[255];
procFile.getline(str, 255);  // delim defaults to '\n'


vector<string> tmp;
istringstream iss(str);
copy(istream_iterator<string>(iss),
     istream_iterator<string>(),
     back_inserter<vector<string> >(tmp));

process_time = (now - boottime) - (atof(tmp.at(21).c_str()))/HZ;

快乐的编码!

答案 1 :(得分:3)

您可以stat /proc/{processid}查看shell的创建时间。

编辑:该文件夹上的fstat应该可以提供您想要的内容(创建时间)。

答案 2 :(得分:1)

让我们分解你想要做的事情:

  1. 获取文件修改时间。
  2. 将时间转换为Unix时间。
  3. 减去两次。
  4. 因此,为了获得当前时间,我们可以运行:

    #include <cstdio>
    #include <cstdlib>
    char *command;
    int process_number = 1; // init process.
    SYSTEM ("mkfifo time_pipe");
    sprintf (command, "stat /proc/%d -printf="%%X" > time_pipe", process_number); // get the command to run.
    // since this directory is created once it starts, we know it is the start time (about)
    // note the %%, which means to print a literal %
    SYSTEM (command); // run the command.
    

    现在,下一步是将其解析为Unix时间 - 但我们没有必要! %X说明符实际上将其转换为Unix时间。所以下一步是(a)得到当前时间(b)减去时间:

    timeval cur_time;
    double current_time, time_passed;
    char read_time[11]; // 32 bit overflows = only 11 digits.
    FILE *ourpipe;
    gettimeofday(&cur_time, NULL);
    current_time = cur_time.tv_sec + (cur_time.tv_usec * 1000000.0);
    // usec stands for mu second, i.e., a millionth of a second. I wasn't there when they named this stuff.
    ourpipe = fopen ("time_pipe", "rb"); 
    fread(read_time, sizeof (char), 10, ourpipe);
    time_passed = current_time - atoi (read_time);
    fclose (ourpipe);
    

    所以是的,这就是它。管道需要从一个输入到另一个输入。

答案 3 :(得分:0)

time命令会为您提供以下信息:

> man 1 time

命令行参数将使其返回

%S     Total number of CPU-seconds that the  process  spent  in  kernel mode.
%U     Total number of CPU-seconds that the process spent in user mode.
%P     Percentage of the CPU that this job got

您可以致电system( char *command )执行编程中的命令。

答案 4 :(得分:0)

  

/ proc / {processid}#好主意!

但为什么不只是阅读/ proc / {processid} / stat,只是得到你想要的任何统计数据?

来自“man proc”:

...
       stat   kernel/system statistics

          cpu  3357 0 4313 1362393
                 The number of jiffies (1/100ths of a second)
                 that the system spent in user mode, user
                 mode with low priority (nice), system mode,
                 and the idle task, respectively.  The last
                 value should be 100 times the second entry
                 in the uptime pseudo-file.

          disk 0 0 0 0
                 The four disk entries are not implemented at
                 this time.  I'm not even sure what this
                 should be, since kernel statistics on other
                 machines usually track both transfer rate
                 and I/Os per second and this only allows for
                 one field per drive.

...

答案 5 :(得分:0)

老话题,但由于我正在处理同样的问题,我想我可能会发布我的回复。也许这对其他人有用。请注意,此代码不应在严肃的生产环境中使用,但作为获取OP所需内容的快速而肮脏的方法,我认为这就足够了。请注意,此代码与响应自己的问题时发布的OP代码相同,但它被修改为能够在从stackexchange复制时直接编译,他的代码无法直接编译。

此代码编译,我添加了一些额外的功能。

说明:启动任何程序,然后执行&#39; ps aux | PROGRAMNAME&#39;得到它的pid。它是左起第二列。现在将该数字输入到main函数中的pid并编译程序。现在,在运行程序时,输出将类似于:

失效:天数:0,小时:0,分钟:5,秒:58

//Original code credit by kmdent.
//http://stackoverflow.com/questions/6514378/how-do-you-get-how-long-a-process-has-been-running
#include <iostream>
#include <iterator>
#include <sstream>
#include <fstream>
#include <vector>
#include <cstring>
#include <cerrno>
#include <ctime>
#include <cstdio>
#include <fcntl.h>
#include <sys/time.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string>
#include "/usr/include/x86_64-linux-gnu/sys/param.h"

using namespace std;


template <class T>
inline std::string to_string (const T& t)
{
    std::stringstream ss;
    ss << t;
    return ss.str();
}

//Return the number of seconds a process has been running.
long lapsed(string pid) {

    int fd;
    char buff[128];
    char *p;
    unsigned long uptime;
    struct timeval tv;
    static time_t boottime;


    if ((fd = open("/proc/uptime", 0)) != -1) {
    if (read(fd, buff, sizeof(buff)) > 0) {
      uptime = strtoul(buff, &p, 10);
      gettimeofday(&tv, 0);
      boottime = tv.tv_sec - uptime;
    }
        close(fd);
    }

    ifstream procFile;
    string f = "/proc/"+pid+"/stat";
    procFile.open(f.c_str());

    char str[255];
    procFile.getline(str, 255);  // delim defaults to '\n'

    vector<string> tmp;
    istringstream iss(str);
    copy(istream_iterator<string>(iss),
         istream_iterator<string>(),
         back_inserter<vector<string> >(tmp));

    std::time_t now = std::time(0);
    std::time_t lapsed = ((now - boottime) - (atof(tmp.at(21).c_str()))/HZ);
    return lapsed;

}

string human_readable_lapsed(long input_seconds) {
    //Credit: http://www.cplusplus.com/forum/beginner/14357/
     long days = input_seconds / 60 / 60 / 24;
     int hours = (input_seconds / 60 / 60) % 24;
     int minutes = (input_seconds / 60) % 60;
     int seconds = input_seconds % 60;

     return "days: " + to_string(days) + " , hours: " + to_string(hours) + " , min: " + to_string(minutes) + " , seconds: " + to_string(seconds);
}

int main(int argc, char* argv[])
{
    //Pid to get total running time for.
    string pid = "13875";
    std::cout << "Lapsed: " << human_readable_lapsed(lapsed(pid)) << std::endl;
    return 0;
}