как вы получаете, как долго процесс запущен? - PullRequest
5 голосов
/ 29 июня 2011

Есть ли способ получить эту информацию из каталога /proc? Я хочу узнать, как долго каждый процесс работал в секундах.

РЕДАКТИРОВАТЬ: Мне нужно было сделать это из C ++. Извините за путаницу.

Ответы [ 6 ]

6 голосов
/ 02 июля 2011

Хорошо, ребята, поэтому, прочитав исходный код команды top, я нашел нехитрый способ получения времени начала процесса. Формула, которую они используют:

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

(Вы должны разделить на HZ, потому что процесс_старт_времени находится в замешательстве)

Получение этих значений:

  • 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 голосов
/ 29 июня 2011

Вы можете сделать stat /proc/{processid} чтобы увидеть время создания в оболочке.

РЕДАКТИРОВАТЬ: fstat в этой папке должно дать вам то, что вы хотите (время создания).*

1 голос
/ 29 июня 2011

Давайте разберемся с тем, что вы пытаетесь сделать:

  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 Time. Поэтому следующим шагом будет (а) получить текущее время (б) вычесть время:

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 голосов
/ 30 апреля 2015

Старая тема, но поскольку я работал над теми же проблемами, я подумал, что могу опубликовать свой ответ. Возможно, это будет полезно для кого-то еще. Обратите внимание, этот код не должен использоваться в серьезной производственной среде, но как быстрый и грязный способ получить то, что ищет OP, я думаю, этого будет достаточно. Обратите внимание, что этот код является тем же кодом, что и ОП, опубликованный в ответ на его собственный вопрос, но он изменен, чтобы его можно было компилировать напрямую, когда вы копируете его из stackexchange, его код не мог напрямую компилироваться.

Этот код скомпилирован, и я добавил несколько дополнительных функций.

Инструкции: Запустите любую программу, затем выполните команду «ps aux | имя программы, чтобы получить свой pid. Это второй столбец слева. Теперь введите это число в pid главной функции и скомпилируйте программу. Теперь при запуске программы вывод будет примерно таким:

Просрочено: дней: 0, часов: 0, мин: 5, секунд: 58

//Original code credit by kmdent.
///4692042/kak-vy-poluchaete-kak-dolgo-protsess-zapuschen
#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;
}
0 голосов
/ 02 июля 2011

/ proc / {processid} # Хорошая идея!

Но почему бы просто не прочитать / proc / {processid} / stat и просто получить любую статистику, которую вы хотите?

из "man proc":

<pre> ... stat kernel/system statistics</p> <pre><code> 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 голосов
/ 29 июня 2011

Команда времени выдаст вам эту информацию:

> 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 ), чтобы выполнить команду из вашей программы.

...