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
Реальное время соответствует обычному определению времени. Когда реальное время отмеряется от какого-то стандартного момента, мы называем его календарным временем; затраченным временем называется время, отмеряемое от какого-либо момента в жизни процесса (обычно от его запуска).
Время процесса представляет собой время центрального процессора, использованное процессом, и разбивается на пользовательский и системный компоненты.
Получить и установить значение системных часов (то есть календарного времени, замеренного в секундах от начала отсчета (Epoch)) позволяют различные системные вызовы, а некоторые библиотечные функции дают возможность выполнять преобразования между календарным временем и другими форматами времени, включая разделенное время (время, разбитое на компоненты) и время в виде читаемых символьных строк. Описание этих преобразований не обходится без рассмотрения вопросов локалей и интернационализации.
Использование времени и даты, а также вывод их на экран важны для многих приложений, и функции, рассмотренные в этой главе, будут еще часто упоминаться на протяжении всей книги. Дополнительно вопросы замеров времени мы также рассмотрим в главе 23.
Дополнительные сведения
Подробности, касающиеся способов замеров времени ядром Linux, можно найти в [Love, 2010].
Подробно о часовых поясах и интернационализации вы можете прочитать в руководстве по GNU-библиотеке C (по адресу http://www.gnu.org/). Подробности относительно локалей также можно найти в документах по SUSv3.
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.