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 outputn");
if (ferror(f)) {
fprintf(stderr, "Error writing to temporary filen");
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.%06ldn",
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 = %dn", priority);
getrlimit(RLIMIT_FSIZE, &r_limit);
printf("Current FSIZE limit: soft = %ld, hard = %ldn",
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 limitn");
setrlimit(RLIMIT_FS1ZE, &r_limit);
work();
exit(0);
}
Выполнив эту программу, вы сможете увидеть, сколько затрачено времени ЦП, и текущий приоритет, с которым программа выполняется. После того как будет задан предельный размер файла, программа не сможет записать во временный файл более 2048 байтов.
$ <b>cc -о limits limits.с -lm</b>
$ <b>./limits</b>
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, и в результате программа выполняется немного дольше.
$ <b>nice ./limits</b>
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, как правило, должны совместно использовать дорогостоящие ресурсы, поэтому в данной главе рассматриваются способы определения имеющихся ресурсов и управления ими.
Глава 5
Терминалы
В этой главе вы познакомитесь с некоторыми улучшениями, которые вам, возможно, захочется внести в базовое приложение из главы 2. Его, быть может, самый очевидный недостаток — пользовательский интерфейс; он достаточно функционален, но не слишком элегантен. Теперь вы узнаете, как сделать более управляемым терминал пользователя, т. е. ввод с клавиатуры и вывод на экран. Помимо этого вы научитесь обеспечивать написанным вами программам возможность получения вводимых данных от пользователя даже при наличии перенаправления ввода и гарантировать вывод данных в нужное место на экране.