times() yields: user CPU=0.00; system CPU: 0.00

After getppid() loop:

clock() returns: 2960000 clocks-per-sec (2.96 secs)

times() yields: user CPU=1.09; system CPU: 1.87

Листинг 10.5. Извлечение затраченного процессом времени ЦП

time/process_time.c

#include

#include

#include "tlpi_hdr.h"

static void /* Вывод сообщения, на которое указывает 'msg',

и показателей времени процесса */

displayProcessTimes(const char *msg)

{

struct tms t;

clock_t clockTime;

static long clockTicks = 0;

if (msg!= NULL)

printf("%s", msg);

if (clockTicks == 0) { /* Извлечение тиков часов в первом вызове */

clockTicks = sysconf(_SC_CLK_TCK);

if (clockTicks == -1)

errExit("sysconf");

}

clockTime = clock();

if (clockTime == -1)

errExit("clock");

printf(" clock() returns: %ld clocks-per-sec (%.2f secs)\n",

(long) clockTime, (double) clockTime / CLOCKS_PER_SEC);

if (times(&t) == -1)

errExit("times");

printf(" times() yields: user CPU=%.2f; system CPU: %.2f\n",

(double) t.tms_utime / clockTicks,

(double) t.tms_stime / clockTicks);

}

int

main(int argc, char *argv[])

{

int numCalls, j;

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().

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

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

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

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

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

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

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

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

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

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

Перейти на страницу:

Похожие книги