2011-06-28 56 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; 
} 
相關問題