Выбрать главу

В упражнении 4.15 показана программа limits.c, имитирующая типичное приложение. Она также задает и нарушает ограничения ресурсов.

Упражнение 4.16. Ограничения ресурсов

1. Включите заголовочные файлы для всех функций, которые вы собираетесь применять в данной программе:

#include <sys/types.h> \

#include <sys/resource.h>

#include <sys/time.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

2. Функция типа void записывает 10 000 раз строку во временный файл и затем выполняет некоторые арифметические вычисления для загрузки ЦП:

void work() {

 FILE *f;

 int i;

 double x = 4.5;

 f = tmpfile();

 for (i = 0; i < 10000; i++) {

  fprintf(f, "Do some output\n");

  if (ferror(f)) {

   fprintf(stderr, "Error writing to temporary file\n");

   exit(1);

  }

 }

 for (i = 0; i < 1000000; i++) x = log(x*x + 3.21);

}

3. Функция main вызывает функцию work, а затем применяет функцию getrusage для определения времени ЦП, использованного work. Эта информация выводится на экран:

int main() {

 struct rusage r_usage;

 struct rlimit r_limit;

 int priority;

 work();

 getrusage(RUSAGE_SELF, &r_usage);

 printf("CPU usage: User = %ld.%06ld, System = %ld.%06ld\n",

  r_usage.ru_utime.tvsec, rusage.ru_utime.tv_usec,

  r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);

4. Далее она вызывает функции getpriority и getrlimit для выяснения текущего приоритета и ограничений на размер файла соответственно:

 priority = getpriority(PRIO_PROCESS, getpid());

 printf("Current priority = %d\n", priority);

 getrlimit(RLIMIT_FSIZE, &r_limit);

 printf("Current FSIZE limit: soft = %ld, hard = %ld\n",

  r_limi t.rlim_cur, r_limit.rlim_max);

5. В заключение задайте ограничение размера файла с помощью функции setrlimit и снова вызовите функцию work, которая завершится с ошибкой, т.к. попытается создать слишком большой файл:

 r_limit.rlim_cur = 2048;

 r_limit.rlim_max = 4096;

 printf("Setting a 2K file size limit\n");

 setrlimit(RLIMIT_FS1ZE, &r_limit);

 work();

 exit(0);

}

Выполнив эту программу, вы сможете увидеть, сколько затрачено времени ЦП, и текущий приоритет, с которым программа выполняется. После того как будет задан предельный размер файла, программа не сможет записать во временный файл более 2048 байтов.

$ cc -о limits limits.с -lm

$ ./limits

CPU usage: User = 0.140008, System = 0.020001

Current priority = 0

Current FSIZE limit: soft = -1, hard = -1

Setting a 2K file size limit

File size limit exceeded

Вы можете изменить приоритет программы, запустив ее с помощью команды nice. Далее показано, как меняется приоритет на значение +10, и в результате программа выполняется немного дольше.

$ nice ./limits

CPU usage: User = 0.152009, System = 0.020001

Current priority = 10

Current FSIZE limit: soft = -1, hard = -1 

Setting a 2K file size limit

File size limit exceeded

Как это работает

Программа limits вызывает функцию work для имитации операций типичной программы. Она выполняет некоторые вычисления и формирует вывод, в данном случае около 150 Кбайт записывается во временный файл. Программа вызывает функции управления ресурсами для выяснения своего приоритета и ограничений на размер файла. В данном случае ограничения размеров файлов не заданы, поэтому можно создавать файл любого размера (если позволяет дисковое пространство). Затем программа задает свое ограничение размера файла, равное примерно 2 Кбайт, и снова пытается выполнить некоторые действия. На этот раз функция work завершается неудачно, поскольку не может создать такой большой временный файл.

Примечание

Ограничения можно также наложить на программу, выполняющуюся в отдельной командной оболочке с помощью команды ulimit оболочки bash.

В приведенном примере сообщение об ошибке "Error writing to temporary file" ("Ошибка записи во временный файл") не выводится. Это происходит потому, что некоторые системы (например, Linux 2.2 и более поздние версии) завершают выполнение программы при превышении ограничения ресурса. Делается это с помощью отправки сигнала SIGXFSZ. В главе 11 вы узнаете больше о сигналах и способах их применения. Другие системы, соответствующие стандарту POSIX, заставляют функцию, превысившую ограничение, вернуть ошибку.

Резюме 

В этой главе вы посмотрели на окружение системы Linux и познакомились с условиями выполнения программ. Вы узнали об аргументах командной строки и переменных окружения — и те, и другие могут применяться для изменения стандартного поведения программы и предоставляют подходящие программные опции.

Вы увидели, как программа может воспользоваться библиотечными функциями для обработки значений даты и времени и получить сведения о себе, пользователе и компьютере, на котором она выполняется.

Программы в ОС Linux, как правило, должны совместно использовать дорогостоящие ресурсы, поэтому в данной главе рассматриваются способы определения имеющихся ресурсов и управления ими.