Преимущества от выполнения процессов на одном и том же ЦПУ не распространяются на гиперпоточные и некоторые современные многопроцессорные архитекторы, в которых процессоры используют общий кэш. В таких системах процессы работают быстрее на разных ЦПУ. Сведения о структуре многопроцессорной системы можно получить, изучив содержимое доступного только в Linux файла /proc/cpuinfo.
36. Ресурсы процессов
Каждый процесс потребляет системные ресурсы, такие как память и процессорное время. Эта глава посвящена системным вызовам, связанным с подобной информацией. Мы начнем с вызова getrusage(), который позволяет процессу следить за ресурсами, потребленными им или его потомками. Затем будут рассмотрены вызовы setrlimit() и getrlimit(), которые позволяют изменять и получать данные об установленных для вызывающего процесса ограничениях на различные ресурсы.
Системный вызов getrusage() возвращает статистику, которая касается различных ресурсов системы, потребленных самим вызывающим процессом или всеми его потомками.
#include
int getrusage(int
Возвращает 0 при успешном завершении или –1, если произошла ошибка
Аргумент who обозначает процесс (-ы), для которого (-ых) будет извлекаться информация о потреблении ресурсов. Он может принимать одно из следующих значений.
• RUSAGE_SELF — вызывает сведения о вызывающем процессе.
• RUSAGE_CHILDREN — возвращает сведения обо всех потомках вызывающего процесса, которые были завершены и которых он ожидал.
• RUSAGE_THREAD (начиная с Linux 2.6.26) — возвращает сведения о вызывающем потоке. Поддерживается только в Linux.
Аргумент res_usage представляет собой указатель на структуру типа rusage, объявление которой показано в листинге 36.1.
Листинг 36.1. Объявление структуры rusage
struct rusage {
struct timeval ru_utime; /* Процессорное время, потребленное пользователем */
struct timeval ru_stime; /* Процессорное время, потребленное системой */
long ru_maxrss; /* Размер страницы памяти, выделенной процессу
(в килобайтах) [используется с Linux 2.6.32] */
long ru_ixrss; /* Интегральный объем (разделяемой) текстовой памяти
(килобайты в секунду) [не используется] */
long ru_idrss; /* Интегральный объем (неразделяемого)
сегмента памяти с данными (килобайты
в секунду) [не используется] */
long ru_isrss; /* Интегральный объем (неразделяемого)
стека (килобайты в секунду) [не используется] */
long ru_minflt; /* Мягкий сбой страницы памяти
(ввод/вывод необязателен) */
long ru_majflt; /* Жесткий сбой страницы памяти
(ввод/вывод обязателен) */
long ru_nswap; /* Количество сбросов физической
памяти на диск [не используется] */
long ru_inblock; /* Блочные операции ввода в файловой
системе [используется с Linux 2.6.22] */
long ru_oublock; /* Блочные операции вывода в файловой
системе [используется с Linux 2.6.22] */
long ru_msgsnd; /* Количество отправленных IPC сообщений
[не используется] */
long ru_msgrcv; /* Количество полученных IPC сообщений
[не используется] */
long ru_nsignals; /* Количество полученных сигналов
[не используется] */
long ru_nvcsw; /* Добровольные переключения контекста (процесс
освободил ЦПУ до истечения выделенного ему
времени) [используется, начиная с Linux 2.6] */
long ru_nivcsw; /* Принудительные переключения контекста (выделенное
время истекло, или начал работу более приоритетный
процесс) [используется, начиная с Linux 2.6] */
};
Согласно комментариям в листинге 36.1 в Linux далеко не все поля структуры rusage заполняются вызовом getrusage() (или wait3() и wait4()), а если и заполняются, то только в относительно новых версиях ядра. Некоторые поля, игнорирующиеся в Linux, используются другими реализациями UNIX. В Linux они присутствуют на случай, если их реализуют в будущем; это позволит избежать изменений структуры rusage, которые могут сломать бинарную совместимость с уже существующими приложениями.
Вызов getrusage() поддерживается в большинстве UNIX-систем, однако стандарт SUSv3 описывает его довольно слабо, упоминая лишь поля ru_utime и ru_stime. В какой-то мере причиной этого является тот факт, что большая часть информации в структуре rusage зависит от конкретной реализации.
Поля ru_utime и ru_stime представляют собой структуры типа timeval (см. раздел 10.1), которые возвращают количество секунд и микросекунд процессорного времени, потребленное процессом в режимах соответственно пользователя и ядра (похожую информацию можно извлечь с помощью системного вызова times(), описанного в разделе 10.7).
Файл /proc/PID/stat, доступный только в Linux, предоставляет некоторые сведения о потреблении ресурсов (процессорное время и сбои страниц памяти) для любых процессов в системе. Подробности ищите на справочной странице proc(5).