2011-06-28 31 views

回答

4

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

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

(你必须HZ因为process_start_time是一会儿的划分)

获取这些值:

  • 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; 

编码快乐!

3

你可以做stat /proc/{processid}看到在shell的创建时间。

编辑:fstat该文件夹应该给你你想要的东西(创建时间)。

+0

好的呼叫。没有想到检查文件夹的创建时间。谢谢! – kmdent

+0

我不认为它会给你创建文件夹的时间。它给你改变时间,修改时间和访问时间。这些都不会给你创建文件夹的时间。 – kmdent

+0

@kmdent:默认情况下,您不会获得创建时间,因为并非所有文件系统都支持它,但请参阅http://stackoverflow.com/questions/5929419/how-to-get-file-creation-date-in-linux为您提供创作时间的潜在解决方案。 – Femi

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)从您的PROG执行命令。

1

让我们打破你想做什么:

  1. 获取文件的修改时间。
  2. 将时间转换为Unix时间。
  3. 减去两次。

因此,为了得到当前的时间,我们可以运行:

#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时间。因此,下一步将是(一)获取当前时间(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); 

所以啊,这是相当多了。需要管道才能将输入从一个输入到另一个。

+0

修改时间与创建时间不同。 Stat给出修改时间,访问时间和更改时间。这实际上不会给你创建过程的时间。你同意吗? – kmdent

+0

@kmdent是的,你似乎是对的。我想另一种方法是:'ps -eo pid,etime'(返回pid的经过时间)。我会相应地更新我的帖子。 – Arka

0

/proc/{processid}#好主意!

但是,为什么不只是读取/ proc/{processid}/stat,并且只是简单地得到你想要的任何统计数据呢?

从“人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. 

...

0

老话题了这一点,但因为我工作的同样的问题,我想我可能会发布我的回应。也许这对其他人有用。请注意,这些代码不应该用在严肃的生产环境中,但是作为一种快速和肮脏的方法来获得OP正在寻找的东西,我认为这就足够了。请注意,此代码与OP为响应他自己的问题发布的代码相同,但它被修改为能够在从stackexchange复制它时直接编译,他的代码无法直接编译。

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

说明:启动任何程序,然后执行'ps aux |程序名'来获得它的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; 
} 
相关问题