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

printf("CLOCKS_PER_SEC=%ld sysconf(_SC_CLK_TCK)=%ld\n\n",

(long) CLOCKS_PER_SEC, sysconf(_SC_CLK_TCK));

displayProcessTimes("At program start: \n");

numCalls = (argc > 1)? getInt(argv[1], GN_GT_0, "num-calls")

: 100000000;

for (j = 0; j < numCalls; j++)

(void) getppid();

displayProcessTimes("After getppid() loop: \n");

exit(EXIT_SUCCESS);

}

time/process_time.c

10.8. Резюме

Реальное время соответствует обычному определению времени. Когда реальное время отмеряется от какого-то стандартного момента, мы называем его календарным временем; затраченным временем называется время, отмеряемое от какого-либо момента в жизни процесса (обычно от его запуска).

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

Получить и установить значение системных часов (то есть календарного времени, замеренного в секундах от начала отсчета (Epoch)) позволяют различные системные вызовы, а некоторые библиотечные функции дают возможность выполнять преобразования между календарным временем и другими форматами времени, включая разделенное время (время, разбитое на компоненты) и время в виде читаемых символьных строк. Описание этих преобразований не обходится без рассмотрения вопросов локалей и интернационализации.

Использование времени и даты, а также вывод их на экран важны для многих приложений, и функции, рассмотренные в этой главе, будут еще часто упоминаться на протяжении всей книги. Дополнительно вопросы замеров времени мы также рассмотрим в главе 23.

Дополнительные сведения

Подробности, касающиеся способов замеров времени ядром Linux, можно найти в [Love, 2010].

Подробно о часовых поясах и интернационализации вы можете прочитать в руководстве по GNU-библиотеке C (по адресу http://www.gnu.org/). Подробности относительно локалей также можно найти в документах по SUSv3.

10.9. Упражнение

10.1. Возьмем систему, где вызов sysconf(_SC_CLK_TCK) возвращает значение 100. Сколько времени пройдет, пока значение типа clock_t, возвращенное функцией times(), снова превратится в 0, при условии, что оно представлено 32-разрядным целым числом? Выполните такое же вычисление для значения CLOCKS_PER_SEC, возвращенного функцией clock().

11. Системные ограничения и возможности

Каждая реализация UNIX накладывает ограничения (limits) на различные системные характеристики и ресурсы и предоставляет возможности (options), определенные в различных стандартах (или отказывает в их предоставлении). Например, можно определить следующее.

• Сколько файлов процесс может одновременно держать открытыми?

• Поддерживает ли система сигналы реального времени?

• Какое наибольшее значение может быть сохранено в переменной типа int?

• Насколько большим может быть список аргументов программы?

• Какова максимальная длина путевого имени?

Можно, конечно, жестко задать ограничения и возможности в самом приложении, но это снизит портируемость, поскольку все ограничения и возможности могут варьироваться:

• в различных реализациях UNIX. Хотя в отдельно взятых реализациях ограничения и возможности могут быть четко прописаны, от реализации к реализации они могут варьироваться. В качестве примера такого ограничения можно привести максимальное значение, которое может быть сохранено в int-переменной;

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

• от одной файловой системы к другой. Например, традиционные файловые системы System V позволяют для имени файла задействовать до 14 байт, а традиционные файловые системы BSD и большинство файловых систем, обычно используемых в Linux, допускают имена файлов длиной до 255 байт.

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

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

• Другие ограничения и возможности могут изменяться в ходе выполнения приложения. Для таких случаев в SUSv3 определяются три функции — sysconf(), pathconf() и fpathconf(). Приложение может вызвать их для проверки ограничений и возможностей данной реализации UNIX.