Top и PS не показывают тот же результат процессора

54

Это связано с этим вопросом.

Когда я бегу, topя получаю следующий результат:

введите описание изображения здесь

PID 3038использует 18% процессора, однако при запуске

введите описание изображения здесь

результат 5,5%. И это число, похоже, не меняется со временем (т. Е. При выполнении той же команды чуть позже) ...

Является ли psкоманда как - то усреднение использования центрального процессора?

Theodor
источник

Ответы:

87

man psв NOTESразделе.

   CPU usage is currently expressed as the percentage of time spent running
   during the entire lifetime of a process.  This is not ideal, and it does not
   conform to the standards that ps otherwise conforms to.  CPU usage is
   unlikely to add up to exactly 100%.

И, думаю, вы знаете, но вы также можете сделать:

top -p <PID>

Редактировать : что касается вашего комментария к другому ответу;

« Хм, да, мне интересно, как получить это (мгновенный процент процессора) от PS »

Краткий ответ: вы не можете.

Почему это так?

Это все равно что просить кого-то посчитать скорость автомобиля по картинке.

Хотя topэто инструмент мониторинга, psэто инструмент снимка. Думайте об этом так: в любой момент процесс использует процессор или нет. Таким образом, у вас есть 0% или 100% нагрузки в этот момент.

Предоставление: Если psдолжно дать мгновенное использование процессора, это будет либо 0%, либо 100%.

top с другой стороны, сохраняйте числа опроса и рассчитывайте нагрузку с течением времени.

psмог бы дать текущее использование - но это потребовало бы от него чтения данных несколько раз и ожидания между каждым чтением. Это не так.

Расчет для PS% процессора

ps рассчитывает загрузку процессора следующим образом:

uptime = общее время работы системы.
ps_time = время запуска процесса, измеренное в секундах от загрузки.
pu_time = общее время процесс использует процессор.

;; Секунды процесс запущен:
секунд = время работы - ps_time
;; Использование:
cpu_usage = pu_time * 1000 / секунд

печать: cpu_usage / 10 "." cpu_usage% 10


Пример: время работы = 344 545 ps_time = 322 462 pu_time = 3,383 секунд = 344 545 - 322 462 = 22 083 cpu_usage = 3,383 * 1000 / 22,083 = 153 печать: 153/10 "." 153% 10 => 15,3

Таким образом, напечатанное число: время, в течение которого процесс использовал процессор в течение его срока службы. Как в примере выше. Он сделал это за 15,3% своей жизни. В 84,7% случаев он не глючил на процессоре.

Поиск данных

psа также topиспользует данные из файлов, хранящихся в /proc/- или псевдофайловой системе с информацией о процессе .

У вас есть несколько корневых файлов, /proc/которые содержат различную информацию об общем состоянии системы. Кроме того, каждый процесс имеет свою собственную подпапку, в /proc/<PID>/которой хранятся данные, относящиеся к процессу. Так, например, у процесса из вашего вопроса была папка в /proc/3038/.

Когда psвычисляет загрузку процессора, он использует два файла:

/ proc / uptime Время работы системы (в секундах) и количество времени, проведенного в режиме ожидания (в секундах).
/ proc / [PID] / stat Информация о состоянии процесса.
  • Из uptimeнего используется первое значение ( uptime ).
  • Из [PID]/statнего используется следующее:
 № Название Описание
14 utime процессорного времени, потраченного в пользовательском коде, измеренное в jiffies
15 циклов времени процессора, потраченного на код ядра, измеренный в jiffies
16 кубометров процессорного времени в пользовательском коде, включая время детей
17 cstime процессорного времени, потраченного на код ядра, включая время от детей 
22 starttime Время начала процесса, измеряется в секундах

Jiffie это часы тик. Кроме того, он использует различные методы, т. Е. sysconf(_SC_CLK_TCK)Для получения значения Hertz системы (количество тактов в секунду) - в конечном счете, используя 100 в качестве запасного после исчерпания других опций.

Итак, если utime1234, а Герц 100, то:

seconds = utime / Hertz = 1234 / 100 = 12.34

Фактический расчет осуществляется путем:

total_time = utime + stime

IF include_dead_children
    total_time = total_time + cutime + cstime
ENDIF

seconds = uptime - starttime / Hertz

pcpu = (total_time * 1000 / Hertz) / seconds

print: "%CPU" pcpu / 10 "." pcpu % 10

Пример (вывод из пользовательского скрипта Bash):

$ ./psw2 30894
System information
           uptime : 353,512 seconds
             idle : 0
Process information
              PID : 30894
         filename : plugin-containe
            utime : 421,951 jiffies 4,219 seconds
            stime : 63,334 jiffies 633 seconds
           cutime : 0 jiffies 0 seconds
           cstime : 1 jiffies 0 seconds
        starttime : 32,246,240 jiffies 322,462 seconds

Process run time  : 31,050
Process CPU time  : 485,286 jiffies 4,852 seconds
CPU usage since birth: 15.6%

Расчет «текущей» нагрузки с помощью ps

Это (немного?) Сомнительная попытка, но хорошо. Давайте попробуем.

Можно использовать время, предоставленное psи рассчитать загрузку процессора из этого. Размышляя об этом, это может быть весьма полезно, с некоторыми ограничениями.

Это может быть полезно для расчета загрузки процессора за более длительный период. То есть вы хотите отслеживать среднюю загрузку процессора plugin-containerв Firefox, выполняя некоторые задачи, связанные с Firefox.

Используя вывод из:

$ ps -p -o cputime, etimes

CODE    HEADER   DESCRIPTION
cputime TIME     cumulative CPU time, "[DD-]hh:mm:ss" format.  (alias time).
etime   ELAPSED  elapsed time since the process was started, [DD-]hh:]mm:ss.
etimes  ELAPSED  elapsed time since the process was started, in seconds.

Я использую etimeболее etimesв этом образце, по расчетам, только немного более ясно. Также я добавляю% cpu для "веселья". То есть, например, bash-скрипт, который можно использовать etimes- или лучше читать из него /proc/<PID>/и т. Д.

Start:
$ ps -p 30894 -o %cpu,cputime,etime,etimes
%CPU     TIME     ELAPSED ELAPSED
 5.9 00:13:55    03:53:56   14036

End:
%CPU     TIME     ELAPSED ELAPSED
 6.2 00:14:45    03:56:07   14167

Calculate times:
            13 * 60 + 55 =    835   (cputime this far)
3 * 3,600 + 53 * 60 + 56 = 14,036   (time running this far)

            14 * 60 + 45 =    885   (cputime at end)
3 * 3,600 + 56 * 60 +  7 = 14,167   (time running at end)

Calculate percent load:
((885 - 835) / (14,167 - 14,036)) * 100 = 38

Процесс использовал процессор 38% времени в течение этого периода.

Посмотри код

Если вы хотите знать, как psэто сделать, и немного знать C, делайте (похоже, вы запускаете Gnome Debain производные) - хорошее отношение в коде к комментариям и т. Д .:

apt-get source procps
cd procps*/ps
vim HACKING
Runium
источник
Я мог бы обновить с дополнительной информацией topи непрерывного мониторинга - или оснастки по задержке ака " ps" с текущей загрузкой процессора.
Runium
2
Действительно отличный ответ!
Теодор
Как насчет расчета общего использования процессора во всей системе. Инструменты пытаются получить загрузку процессора через снимок или усредняют его по времени?
CMCDragonkai
4
man top

%CPU  --  CPU usage
The  task's share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time.  In a true SMP environment, if 'Irix
mode' is Off, top will operate in 'Solaris mode' where a task's cpu usage will be divided by the total number of CPUs.  You toggle  'Irix/Solaris'  modes
with the 'I' interactive command.


man ps 
%cpu       %CPU    cpu utilization of the process in "##.#" format. Currently, it is the CPU time used divided by the time the process has been running                       (cputime/realtime ratio), expressed as a percentage. It will not add up to 100% unless you are lucky. (alias pcpu).
Рахул Патил
источник
Хм, да, мне интересно, как получить это (мгновенный процент загрузки процессора) отps
Теодор
2
Вы можете извлечь из главного примераtop -p 3343 -n1 | awk '/ R /{print $10}'
Рахул Патил
1
Потрясающие. Я обнаружил, что awk: Инг для pidлучше работал, как вtop -p 3343 -n1 | awk '/ 3343 /{print $10}'
Теодор
1
Спасибо "top -p" приятно, я никогда не замечал эту опцию! Однако мне не нравится искать PID, что если случайно появятся те же цифры в разделе свободной памяти или что-то в этом роде. В моей системе информация находится в 8-й строке и 9-м столбце, поэтому я делаю это:top -p $PID -n1 | awk '{if (NR ==8) print $9 }'
phil_w