Каждый процесс потребляет системные ресурсы, такие как память и процессорное время. Этот пост расскажет вам о системных вызовах, которые необходимы для получения подобной информацией о потребляемых ресурсах и контроля ряда ограничений.
Мы начнем с вызова getrusage(), который позволяет процессу следить за ресурсами, потребленными им или его потомками. Затем будут рассмотрены вызовы setrlimit() и getrlimit(), которые позволяют изменять и получать данные об установленных для вызывающего процесса ограничениях на различные ресурсы.
Ресурсы, использующиеся процессом:
Системный вызов getrusage() возвращает статистику, которая касается различных ресурсов системы, потребленных самим вызывающим процессом или всеми его потомками:
#include <sys/resource.h>
int getrusage(int who, struct rusage *res_usage);
Данный вызов возвращает 0 при успешном завершении или –1, если произошла ошибка. Аргумент who обозначает процесс, для которого будет извлекаться информация о потреблении ресурсов. Он может принимать одно из следующих значений:
1. RUSAGE_SELF — возвращает сведения о вызывающем процессе.
2. RUSAGE_CHILDREN — возвращает сведения обо всех потомках вызывающего процесса.
3. RUSAGE_THREAD — возвращает сведения о вызывающем потоке (поддерживается только в Linux).
Аргумент res_usage представляет собой указатель на структуру типа rusage, поля которой заполняются в момент вызова:
struct rusage {
/* Процессорное время, потребленное пользователем */
struct timeval ru_utime;
/* Процессорное время, потребленное системой */
struct timeval ru_stime;
/* Размер страницы памяти, выделенной процессу */
long ru_maxrss;
...
}
Нужно помнить, что далеко не все поля структуры rusage заполняются вызовом getrusage(). Некоторые поля могут игнорироваться в Linux, но учитываться в других реализациях UNIX. В Linux они присутствуют на случай, если их реализуют в будущем - это позволит поддерживать бинарную совместимость с уже существующими приложениями.
Давайте на примере посмотрим, как можно получить "user/system" процессорное время, затраченное процессом на выполнение кода:
#include <stdio.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
void main() {
/* Some Work... */
struct rusage usage;
if (getrusage(RUSAGE_SELF, &usage) == 0) {
printf("User CPU time: %ld.%06ld seconds\n",
usage.ru_utime.tv_sec, usage.ru_utime.tv_usec);
printf("System CPU time: %ld.%06ld seconds\n",
usage.ru_stime.tv_sec, usage.ru_stime.tv_usec);
}
}
Ограничения на ресурсы для отдельных процессов:
Каждый процесс обладает набором параметров, с помощью которых можно ограничить объем тех или иных системных ресурсов, которые он может потребить. Сведения об ограничениях на ресурсы процесса можно получать и изменять с помощью системных вызовов getrlimit() и setrlimit():
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
Аргумент resource обозначает ограничение на ресурсы, которое нужно получить либо изменить. Рассмотрим несколько примеров возможных значений:
RLIMIT_AS Размер виртуальной памяти процесса (байты)
RLIMIT_CORE Размер дампа памяти (байты)
RLIMIT_CPU Процессорное время (секунды)
...
Аргумент rlim используется либо для возвращения существующих значений ограничения, либо для задания новых. Он представляет собой структуру, состоящую из двух полей:
struct rlimit {
rlim_t rlim_cur;
rlim_t rlim_max;
};
Эти поля имеют целочисленный тип rlim_t и соответствуют двум ограничениям на один ресурс: мягкому (rlim_cur) и жесткому (rlim_max). Эти ограничения управляют тем, какой объем целевого ресурса может быть использован.
Мягкое ограничение регулирует количество ресурсов, которые могут быть использованы процессом. Процесс может использовать ресурсы в пределах этого значения. Жесткое ограничение является абсолютным максимумом, который нельзя превысить, даже при попытке изменить мягкое ограничение.
Linux++ | IT-Образование