Команда ps
в системе, совместимой с POSIX, может вывести время начала процесс, известный как «STIME». Есть ли соответствующий системный вызов POSIX, который я могу сделать на C для определения времени запуска процесса по PID?
Как я могу получить время начала (STIME) процесса с учетом его PID в C в соответствии с POSIX?
Ответы (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
вычислила продолжительность.
etime
на самом деле лучше, чем использование ps -f
со столбцом STIME
. Проблема в том, что STIME
не имеет стандартного формата и procps -ng ps использует три возможных формата с strftime
для вывода времени в зависимости от того, как давно это было.
- person KamilCuk; 24.12.2019
/proc
(не переносимый и не POSIX, но я помню, что это было просто и работало), но я посмотрел на это на сервере Centos 7 и время в /proc/self
больше не были постоянными, и ни один из них не отражал фактическое время запуска моей оболочки.
- person Andrew Henle; 24.12.2019
popen("ps")
, а затем проанализирует вывод. - person KamilCuk   schedule 24.12.2019/proc/<pid>/stat
. - person Barmar   schedule 24.12.2019