有没有办法从/proc
目录中获取这些信息?我希望能够获得每个进程在几秒钟内运行了多长时间。
编辑:我需要从 C++ 中做到这一点。对困惑感到抱歉。
有没有办法从/proc
目录中获取这些信息?我希望能够获得每个进程在几秒钟内运行了多长时间。
编辑:我需要从 C++ 中做到这一点。对困惑感到抱歉。
好的伙计们,在阅读了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;
快乐编码!
您可以stat /proc/{processid}
在 shell 中查看创建时间。
编辑:该文件夹上的fstat应该给你你想要的(创建时间)。
让我们分解一下您要执行的操作:
因此,为了获取当前时间,我们可以运行:
#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);
所以,是的,差不多就是这样。需要管道将输入从一个输入到另一个。
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 执行命令。
/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.
...
这是老话题,但由于我正在处理相同的问题,我想我可能会发布我的回复。也许它对其他人有用。请注意,此代码不应在严肃的生产环境中使用,但作为一种快速而肮脏的方式来获取 OP 正在寻找的内容,我认为这已经足够了。请注意,此代码与OP在回答他自己的问题时发布的代码相同,但是当您从stackexchange复制时将其修改为可以直接编译,他的代码无法直接编译。
这段代码可以编译,并且我添加了一些额外的函数。
说明:启动任何程序,然后执行 'ps aux | 程序名'来获取它的 pid。它是左起第二列。现在将该数字输入到主函数中的 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;
}