Ограничения на ресурсы относятся к отдельным процессам, однако в некоторых случаях они измеряются для всех процессов с одним и тем же реальным идентификатором пользователя. Хорошим примером, объясняющим данный подход, является ограничение RLIMIT_NPROC, которое устанавливает максимальное количество доступных для создания процессов. Если применить его только к потомкам, создаваемым самим процессом, это принесет мало пользы, так как каждый потомок тоже может создавать свои собственные дочерние процессы, а те, в свою очередь, могут делать то же самое и т. д. Поэтому данное ограничение относится ко всем процессам, которые имеют один и тот же реальный пользовательский идентификатор. Однако стоит отметить, что ограничение на ресурсы проверяется только в процессе, в котором оно было установлено (то есть в самом процессе и в его потомках, которые унаследовали ограничение). Если процесс с тем же реальным пользовательским идентификатором его не устанавливал (то есть он у него бесконечный) или имеет другое ограничение, количество потомков, доступных для создания, будет ограничено его собственным ограничением.
При описании каждого ограничения на ресурсы мы будем отмечать те из них, которые распространяются на все процессы с одним и тем же реальным идентификатором пользователя. Если такого примечания нет, это означает, что ограничение касается потребления ресурсов только самим процессом.
Имейте в виду, что часто единицы измерения, которые применяются в консольных командах для получения и установления ограничений на ресурсы (ulimit в bash и ksh или limit в csh), отличаются от тех, что действуют в вызовах getrlimit() и setrlimit(). Например, для выражения ограничений на размер различных сегментов памяти консольные команды обычно используют килобайты.
Таблица 36.1. Значения ресурсов для вызовов getrlimit() и setrlimit()
resource — Ограничение на — SUSv3
RLIMIT_AS — Размер виртуальной памяти процесса (байты) — *
RLIMIT_CORE — Размер дампа памяти (байты) — *
RLIMIT_CPU — Процессорное время (секунды) — *
RLIMIT_DATA — Сегмент с данными процесса (байты) — *
RLIMIT_FSIZE — Размер файла (байты) — *
RLIMIT_MEMLOCK — Заблокированную память (байты) —
RLIMIT_MSGQUEUE — Количество байтов, выделенных под очереди POSIX-сообщений для реального пользовательского идентификатора (начиная с Linux 2.6.8) —
RLIMIT_NICE — Значение nice (начиная с Linux 2.6.12) —
RLIMIT_NOFILE — Максимальное количество файловых дескрипторов плюс один — *
RLIMIT_NPROC — Количество процессов с реальным идентификатором пользователя —
RLIMIT_RSS — Размер страницы памяти (байты; не реализован) —
RLIMIT_RTPRIO — Приоритет планирования в реальном времени (начиная с Linux 2.6.12) —
RLIMIT_RTTIME — Реальное процессорное время (микросекунды; начиная с Linux 2.6.25) —
RLIMIT_SIGPENDING — Количество сигналов в очереди для реального идентификатора пользователя (начиная с Linux 2.6.8) -
RLIMIT_STACK — Размер стека (байты) — *
Прежде чем переходить к подробностям каждого ограничения, рассмотрим простой пример их использования. В листинге 36.2 определяется функция printRlimit(), которая выводит сообщение, а также мягкое и жесткое ограничения для заданного ресурса.
Тип данных rlim_t обычно имеет тот же вид, что и off_t; он применяется для представления ограничения на размер файла, RLIMIT_FSIZE. По этой причине при выводе значений rlim_t мы приводим их к типу long long и указываем в функции printf() спецификатор %lld (подробней об этом в разделе 5.10).
Программа, представленная в листинге 36.3, вызывает setrlimit(), чтобы установить мягкое и жесткое ограничения на количество процессов, которые пользователь может создать (RLIMIT_NPROC); для вывода значения ограничений до изменения и после применяется функция printRlimit(). В конце программа пытается создать как можно больше дочерних процессов. Если запустить ее с аргументами 30 (для мягкого ограничения) и 100 (для жесткого ограничения), мы увидим следующее:
$ ./rlimit_nproc 30 100
Initial maximum process limits: soft=1024; hard=1024
New maximum process limits: soft=30; hard=100
Child 1 (PID=15674) started
Child 2 (PID=15675) started
Child 3 (PID=15676) started
Child 4 (PID=15677) started
ERROR [EAGAIN Resource temporarily unavailable] fork
В этом примере программа сумела создать всего четыре новых процесса, поскольку 26 процессов уже выполнялось от имени текущего пользователя.
Листинг 36.2. Вывод ограничений на ресурсы процесса
procres/print_rlimit.c
#include
#include "print_rlimit.h" /* Объявление функции, которая здесь определяется */
#include "tlpi_hdr.h"
int /* Выводим 'msg' и ограничение для 'resource' */
printRlimit(const char *msg, int resource)
{
struct rlimit rlim;
if (getrlimit(resource, &rlim) == –1)
return –1;
printf("%s soft=", msg);
if (rlim.rlim_cur == RLIM_INFINITY)
printf("infinite");
#ifdef RLIM_SAVED_CUR /* Не определено в некоторых системах */
else if (rlim.rlim_cur == RLIM_SAVED_CUR)