c++ 如何获得进程已经运行了多长时间?

lnvxswe2  于 2022-11-19  发布在  其他
关注(0)|答案(7)|浏览(163)

有没有办法从/proc目录中获取这些信息?我希望能够得到每个进程在秒上运行了多长时间。
编辑:我需要从C++中做这个。很抱歉造成了混乱。

aurhwmvo

aurhwmvo1#

好了,各位,在阅读了top命令的源代码之后,我找到了一种获取进程开始时间的简单方法。他们使用的公式是:

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

(You必须除以HZ,因为process_start_time以jifies为单位)
获取这些值:

  • current_time-您可以从C命令gettimeofday()中获取此信息。
  • boot_time-此值位于/proc/uptime中。此文件包含两个数字:系统的正常运行时间(秒)和空闲进程所花费的时间(秒)。
  • process_start_time-此值位于/proc/[PID]/stat中。系统 Boot 和进程启动之间的时间差(以jifies为单位)。(如果按空格分隔,则为文件中的第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;

快乐编码!

ddrv8njm

ddrv8njm2#

您可以执行stat /proc/{processid}来查看shell的创建时间。
EDIT:该文件夹上的fstat应该会给予你想要的(创建时间)。

zvokhttg

zvokhttg3#

让我们分解一下您要做的事情:
1.获取文件的修改时间。
1.将时间转换为Unix时间。
1.减去这两次。
因此,为了获得当前时间,我们可以运行:

#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);

所以,是的,差不多就是这样。需要管道将输入从一个传输到另一个。

q0qdq0h2

q0qdq0h24#

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中执行命令。

jtoj6r0c

jtoj6r0c5#

/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.

 ...
aurhwmvo

aurhwmvo6#

老主题了,但是由于我也在处理同样的问题,我想我可以发布我的回复。也许它对其他人有用。注意,这段代码不应该在严肃的生产环境中使用,但是作为一种快速和肮脏的方式来获得OP正在寻找的东西,我认为这就足够了。注意,这段代码与OP在回复他自己的问题时发布的代码相同,但是当你从stackexchange复制它的时候,它被修改成能够直接编译,他的代码不能直接编译。
这段代码编译后,我添加了一些额外的函数。
使用说明:启动任何程序,然后执行'ps aux| programname'来得到它的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;
}
xvw2m8pv

xvw2m8pv7#

下面是我用Qt在C++中实现它的方法:https://github.com/carlonluca/procweb/blob/756cc3607250057520bc107cb612b2b1d40d1cd0/procweb-qt/pwsampler.cpp#L141。
1.读取文件/proc/<pid>/stat
1.取索引21处的值。
1.读取系统正常运行时间[1]。
1.使用sysconf(_SC_CLK_TCK)读取每秒时钟滴答数。
1.计算正常运行时间- startTime。

qint64 startTime = 0;
if (procStatValues.size() > 21)
    if (long int clockTick = sysconf(_SC_CLK_TCK))
        startTime = qRound64(lqt::string_to_uint64(procStatValues[21], 0)/static_cast<double>(clockTick))*1000;

【1】

std::optional<quint64> PWSampler::readSysUptimeMillis()
{
    QFile f(QSL("/proc/uptime"));
    if (!f.open(QIODevice::ReadOnly)) {
        qWarning() << "Could not open /proc/uptime";
        return std::nullopt;
    }

    QString s = f.readAll();
    QStringList tokens = s.split(' ');
    if (tokens.size() != 2) {
        qWarning() << "Cannot parse /proc/uptime content";
        return std::nullopt;
    }

    double uptimeSecs = lqt::string_to_float(tokens[0], -1);
    if (uptimeSecs < 0) {
        qWarning() << "Cannot parse /proc/uptime content";
        return std::nullopt;
    }

    return qRound64(uptimeSecs*1000);
}

相关问题