Как я могу получить время начала (STIME) процесса с учетом его PID в C в соответствии с POSIX?

Команда ps в системе, совместимой с POSIX, может вывести время начала процесс, известный как «STIME». Есть ли соответствующий системный вызов POSIX, который я могу сделать на C для определения времени запуска процесса по PID?


person Jack M    schedule 23.12.2019    source источник
comment
Я считаю, что вызов posix будет popen("ps"), а затем проанализирует вывод.   -  person KamilCuk    schedule 24.12.2019
comment
Кстати, если не обман: stackoverflow.com/questions/5731234/   -  person Andrew Henle    schedule 24.12.2019
comment
Для этого нет POSIX API. В Linux вы можете получить его от /proc/<pid>/stat.   -  person Barmar    schedule 24.12.2019


Ответы (1)


Единственным переносимым, совместимым с POSIX способом является анализ вывода команды ps -o etime ... для получения длительности в днях, часах, минутах и ​​секундах с момента запуска процесса. быть способом заставить столбец STIME ps -f ... обеспечить точное определение времени. GNU/Linux ps, например, урежет столбец STIME до формата MMMDD без переносимого способа расширения.

Согласно документации POSIX ps:

...

Параметр -o позволяет указать формат вывода под контролем пользователя.

Приложение должно гарантировать, что спецификация формата представляет собой список имен, представленных как один аргумент или разделенных. Каждая переменная имеет заголовок по умолчанию. Заголовок по умолчанию можно переопределить, добавив и новый текст заголовка. Остальные символы в аргументе должны использоваться как текст заголовка. Указанные поля должны быть записаны в порядке, указанном в командной строке, и должны быть расположены в столбцах в выводе. Ширина поля должна быть выбрана системой так, чтобы она была не меньше ширины текста заголовка (значение по умолчанию или переопределенное значение). Если текст заголовка нулевой, например -o user=, ширина поля должна быть не меньше ширины текста заголовка по умолчанию. Если все текстовые поля заголовка пусты, строка заголовка не записывается.

Следующие имена распознаются в локали POSIX:

...

время

В локали POSIX время, прошедшее с момента запуска процесса, в виде:

[[dd-]hh:]mm:ss

где dd обозначает количество дней, hh количество часов, mm количество минут и ss количество секунд. Поле dd должно быть десятичным целым числом. Поля hh, mm и ss должны быть двузначными десятичными целыми числами, дополненными слева нулями.

...

Например, если вы знаете идентификатор процесса:

sprintf( buffer, "ps -o etime= -p %lld", ( long long ) pid );

FILE *pp = popen( buffer, "r" );

Если вы хотите получить все процессы:

FILE *pp = popen( "ps -eo pid= -o etime=", "r" );

Обратите внимание на использование = после каждого спецификатора формата. = можно использовать со спецификаторами формата для обозначения заголовка столбца. Если оставить все заголовки столбцов пустыми, строка заголовка не выдается, что упрощает синтаксический анализ.

Вам нужно будет проанализировать каждую строку и сравнить продолжительность с текущим временем, чтобы получить приблизительное время начала процесса. Время, которое вы получите, может быть искажено любыми обновлениями времени в системе, и оно не будет точным более чем на секунду или около того, так как самой команде ps потребуется время для запуска, и вы не сможете выбрать правильный «текущее время», чтобы сравнить каждую отдельную строку из вывода ps, поскольку вы не можете сказать, как команда ps вычислила продолжительность.

person Andrew Henle    schedule 23.12.2019
comment
Использование etime на самом деле лучше, чем использование ps -f со столбцом STIME. Проблема в том, что STIME не имеет стандартного формата и procps -ng ps использует три возможных формата с strftime для вывода времени в зависимости от того, как давно это было. - person KamilCuk; 24.12.2019
comment
@KamilCuk Приятно, что он может рухнуть до года. :-( Кажется, я помню, как в прошлом получал время модификации файла в /proc (не переносимый и не POSIX, но я помню, что это было просто и работало), но я посмотрел на это на сервере Centos 7 и время в /proc/self больше не были постоянными, и ни один из них не отражал фактическое время запуска моей оболочки. - person Andrew Henle; 24.12.2019