Next Previous Contents

17. Дата и время

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

Функции времени относятся к трем категориям:

17.1 Время Процессора

Если вы пробуете оптимизировать вашу программу или измерять эффективность, очень полезно знать, сколько времени процессора или CPU времени она использовала в любой заданной точке. Процессорное время является отличным от фактических часов, потому что оно не включает все потраченное время на ожидание ввода-вывода или когда выполняется некоторый другой процесс. Процессорное время представляется типом данных clock_t, и дано как ряд импульсов времени относительно произвольного базового времени, отмечающего начало одиночного вызова программы.

Запрос Основного Времени CPU

Чтобы получить прошедшее CPU время, используемое процессом, Вы можете использовать функцию clock. Это средство объявлено в заглавном файле " time.h ".

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

                         #include <time.h>
                         clock_t start, end;
                         double elapsed;
                         start = clock();
                         . . . /* Do the work. */
                         end = clock();
                         elapsed=((double)(end-start))/CLOCKS_PER_SEC;
Различные компьютеры и операционные системы сильно отличаются в том, как они следят за процессорным временем. Общее для внутренних часов процессора то, что разрешающая способность где-то между тысячной и милионной долей секунды.

В системе GNU, clock _t эквивалентен long int, а CLOCKS_PER_SEC - целочисленное значение. Но в других системах, и clock _t и тип макрокоманды CLOCKS_PER_SEC может быть или целое число, или с плавающей точкой. Приведением значения времени процессора к double, см. пример выше, удостоверяется, что нужные операции работают правильно и последовательно независимо от того, каково основное представление.

       int CLOCKS_PER_SEC
Значение этой макрокоманды - число импульсов времени в секунду, измеряемое функцией clock.
       int CLK_TCK
Это - устаревшее имя для CLOCKS_PER_SEC.
       clock_t     (тип данных)
Это - тип значения, возвращенного функцией clock. Значения типа clock_t измеряются в единицах импульсов сигналов времени clock.
       clock_t clock (void)  (функция)
Эта функция возвращает прошедшее процессорное время. Базовое время произвольно, но не изменяется внутри одиночного процесса. Если процессорное время не доступно или не может представляться, clock возвращает значение (clock_t) (-1).

Детализированный Запрос Времени CPU

Функция times возвращает более детализированную информацию относительно прошедшего процессорного времени в struct tmsobject. Вы должны включить заглавный файл " sys/times.h " чтобы использовать это средство.

       struct tms          (тип данных)
Структура tms используется, чтобы возвратить информацию относительно времени процесса. Она содержит по крайней мере следующие элементы:
       clock_t tms_utime
Это - процессорное время, используемое при выполнении команд вызывающего процесса.
       clock_t tms_stime
Это - процессорное время, используемое системой от имени вызываюлщего процесса.
       clock_t tms_cutime
Это - сумма значений tms_utime и значений tms_cutime всех завершенных дочерних процессов данного процесса. Другими словами, она представляет общее процессорное время, используемое при выполнении команд всех завершенных дочерних процессов вызывающего процесса.
       clock_t tms_cstime
Подобно tms_cutime, но представляет общее процессорное время, используемое системой от имени всех завершенных дочерних процессов.

Все времена даны в импульсах сигналов времени. Они - абсолютные значения; в новом процессе, они - все нуль. См. Раздел 23.4 [Создание Процесса].

       clock_t times (struct tms *buffer)  (функция)
Функция times сохраняет процессорное время для вызывающего процесса в buffer.

Возвращаемое значение - также как значение clock (): прошедшее реальное время относительно произвольной основы. Основа - константа внутри специфического процесса, и обычно представляет время начиная с запуска системы. Значение (clock_t) (-1) возвращается, чтобы указать отказ.

Примечание Переносимости: функция clock, описанная в Разделе 17.1.1 [Базисное процессорное Время], определена в соответствии c стандартом ANSI C. Функция times - возможность POSIX.1. В системе GNU, значение, возвращенное функцией clock эквивалентно сумме tms_utime и tms_stime полей, возвращенных times.

17.2 Календарное Время

Этот раздел описывает средства для слежения за датами и временем согласно Грегорианскому календарю.

Имеются три представления информации даты и времени:

Простое Календарное Время

Этот раздел описывает time_t тип данных для представления календарного времени, и функции, которые используют объекты календарного времени. Эти средства объявлены в заглавном файле " time.h ".

       time_t 
Это - тип данных, используемый, чтобы представить календарное время. В библиотеке GNU C и других POSIX-реализациях, time_t эквивалентен long int. Он интерпретируется как абсолютное значение времени и представляет число секунд, истекающих с 00:00:00 1 января, 1970, Координированного Универсального Времени. (Эта дата иногда упоминается как эпоха.)

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

       double difftime (time_t time1, time_t time0)  (функция)
Функция difftime возвращает число секунд, между временем time1 и временем time0, как значение типа double.

В системе GNU, Вы можете просто вычитать значения time_t. Но в других системах, time_t тип данных может использовать некоторое другое кодирование, где вычитание не работает непосредственно.

       time_t time (time_t *result) 
Функция time возвращает текущее время как значение типа time_t. Если аргумент result - не пустой указатель, значение time, также будет сохранено в *result. Если календарный time не доступен, возвращается значение (time_t) (-1).

Календарь с высоким разрешением

Тип данных time_t, используемый, чтобы представить календарное вермя имеет разрешающую способность только в одну секунду.

Некоторые приложения нуждаются в большей точности.

Так, библиотека GNU C также содержит функции, которые способны представить календарь с более высокой разрешающей способностью чем одна секунда. Функции и связанные типы данных, описанные в этом разделе объявлены в " sys/time.h ".

       struct timeval  (тип данных)
Структура struct timeval представляет календарное время. Она имеет следующие элементы:
       long int tv_sec
Этот представляет число секунд начиная с зпохи. Это эквивалентно нормальному значению time_t.
       long int tv_usec
Это - дробное второе значение, представляемое как число микросекунд.

Некоторые значения struct timeval - используются для временных интервалов. Тогда tv_sec элемент - число секунд в интервале, а tv_usec - число микросекунд.

       struct timezone  (тип данных)
Структура struct timezone используется, чтобы содержать минимальную информацию относительно зоны местного времени. Она имеет следующие элементы:
       int tz_minuteswest
Это - число минут к западу от ГРИНВИЧа.
       int tz_dsttime
Если отличен от нуля, сдвинутое время применяется в течение некоторой части года. Struct timezone устаревший тип и не должен использоваться. Вместо этого, используйте средства, описанные в Разделе 17.2.6 [Функции Часового пояса].

Часто необходимо вычесть два значения типа struct timeval. Вот самый лучший способ делать это. Он работает даже на некоторых специфических операционных системах, где tv_sec элемент имеет тип unsigned.

         int
         timeval_subtract (result, x, y)
                         struct timeval *result, *x, *y;
         {
                 if (x->tv_usec < y->tv_usec) {
                         int nsec = (y->tv_usec-x->tv_usec)/1000000+1;
                         y->tv_usec -= 1000000 * nsec;
                         y->tv_sec += nsec;
                 }
                 if (x->tv_usec - y->tv_usec > 1000000) {
                         int nsec = (y->tv_usec-x->tv_usec)/1000000;
                         y->tv_usec += 1000000 * nsec;
                         y->tv_sec -= nsec;
                 }
                 result->tv_sec = x->tv_sec - y->tv_sec;
                 result->tv_usec = x->tv_usec - y->tv_usec;
                 return x->tv_sec < y->tv_sec;
         }
       int gettimeofday (struct timeval *tp, struct timezone *tzp) (функция)
Функция gettimeofday возвращает текущую дату и время в структуре struct timeval, обозначенной tp. Информация относительно часового пояса возвращается в структуре, указанной в tzp. Если аргумент tzp является пустым указателем, информация часового пояса, игнорируется.

Возвращаемое значение - 0 при успехе и -1 при отказе. Следующее errno условие ошибки определено для этой функции:

ENOSYS

операционная система не поддерживает получение информации часового пояса, и tzp - не пустой указатель. Операционная система GNU не поддерживает использование struct timezoneto для представления информации часового пояса; это - устаревшая возможность 4.3 BSD. Вместо этого, используйте средства, описанные в Разделе 17.2.6 [Функции Часового пояса].

       int settimeofday (const struct timeval *tp, const struct timezone *tzp)
Функция settimeofday устанавливает текущую дату и время согласно аргументам. Что касается gettimeofday, информация часового пояса игнорируется, если tzp - пустой указатель.

Вы должны быть привилегированным пользователем, чтобы использовать settimeofday.

Возвращаемое значение - 0 при успехе и -1 при отказе. Следующие errno условия ошибки определены для этой функции:

EPERM

Этот процесс не может устанавливать время, потому что он не привилегированный.

ENOSYS

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

       int adjtime (const struct timeval *delta, struct timeval *olddelta)
Эта функция ускоряет или замедляет часы системы, чтобы делать постепенные корректировки текущего времени. Она гарантирует, что время, сообщенное часами системы всегда монотонно увеличивается, чего не могло случаться, если Вы просто устанавливаете текущее время.

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

Если аргумент olddelta - не пустой указатель, функция adjtime, возвращает информацию относительно любой предыдущей корректировки, которая еще не завершилась.

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

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

EPERM

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

Примечание Переносимости: функции gettimeofday, settimeofday, и adjtime - из BSD.

Разделенное Время

Календарное время представляется как число секунд. Это удобно для вычисления, но не имеет никакого отношения к способу, которым люди обычно представляют даты и время. Нпротив, разделенное время ­ двоичное представление, разделенное на год, месяц, день, и так далее.

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

Символы в этом разделе объявлены в заглавном файле " time.h ".

       struct tm  
Это - тип данных, используемый, чтобы представить разделенное время. Структура содержит по крайней мере следующие элементы, которые могут появляться в любом порядке:
       int tm_sec
Это - число секунд, обычно в диапазоне от 0 до 59. (Фактическое верхнее ограничение 61, учитывая " прыгающие секунды ".)
       int tm_min
Это - число минут, в диапазоне от 0 до 59.
       int tm_hour
Это - число часов после полуночи, в диапазоне от 0 до 23.
       int tm_mday
Это - день месяца, в диапазоне от 1 до 31.
       int tm_mon
Это - число месяцев начиная с января, в диапазоне от 0 до 11.
       int tm_year
Это - число лет начиная с 1900.
       int tm_wday
Это - число дней начиная с воскресенья, в диапазоне от 0 до 6.
       int tm_yday
Это - число дней начиная с 1 января, в диапазоне от 0 до 365.
       int tm_isdst
Это - флаг, который указывает действует ли Смещение светового дня (или было, или будет) на описанное время. Значение положительно, если Смещение светового дня включено, нуль, если нет, и отрицательно, если информация не доступна.
       long int tm_gmtoff
Это поле описывает часовой пояс, который использовался, чтобы вычислить разделенное значение времени; это значение Вы должны добавить к местному времени в этой зоне, чтобы получить время ПО ГРИНВИЧУ, в секундах. Значение анологично переменной timezone (см. Раздел 17.2.6 [Функции Часового пояса]).

Tm_gmtoff поле ­ расширение библиотеки GNU.

       const char *tm_zone
Это поле - трехсимвольное имя для часового пояса, который использовался, чтобы вычислить разделенное время. Это - расширение библиотеки GNU.
       struct tm * localtime (const time_t *time)  (функция)
Localtime функция преобразовывает календарное время, указываемое TIME в разделенное представление времени, выраженное относительно заданного часового пояса.

Возвращаемое значение - указатель на статическую структуру разделенного времени, которая могла бы быть записана поверх последующими обращениями к любой из функций date и time. (Но никакая другая библиотечная функция не записывает поверх содержимого этого объекта.)

Вызов localtime имеет и другой эффект: она устанавливает переменную tzname с информацией относительно текущего часового пояса. См. Раздел 17.2.6 [Функции Часового пояса].

       struct tm * gmtime (const time_t *time)  (функция)
Эта функция подобна localtime, за исключением того, что разделенное время выражено как Координированное Универсальное Время (UTC) то есть как Время ПО ГРИНВИЧУ а не относительно зоны местного времени.

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

       time_t mktime (struct tm *brokentime)  (функция)
Mktime функция используется, чтобы преобразовать структуру разделенного времени в календарное время. Она также "нормализует" содержимое структуры разделенного времени, внося день недели и день года, основываясь на других компонентах даты и времени.

Mktime функция игнорирует заданное содержимое tm_wday и tm_yday элементов структуры разделенного времени. Она использует значения других компонентов, чтобы вычислить календарное время; для этих компонентов допустимо иметь ненормализованные значения вне их нормальных диапазонов. Еще mktime корректирует компоненты структуры brokentime (включая tm_wday и tm_yday).

Если заданное разделенное время не может представляться как календарное время, mktime, возвращает значение (time_t) (-1) и не изменяет содержимое brokentime.

Вызов mktime также устанавливает переменную tzname с информацией относительно текущего часового пояса. См. Раздел 17.2.6 [Функции Часового пояса].

Форматирование Даты и времени

Функции, описанные в этом разделе форматирнуют значения времени как строки. Эти функции объявлены в заглавном файле " time.h ".

       char * asctime (const struct tm *brokentime)  (функция)
Функция asctime преобразовывает значение разделенного времени, на которое указывает brokentime в строку в стандартном формате:
                 "Tue May 21 13:46:22 1991\n"
Сокращения для дней недели: `Sun', `Mon', `Tue', `Wed', `Thu', `Fri', and `Sat'.

Сокращения для месяцев: `Jan', `Feb', `Mar', `Apr', `May', `Jun', `Jul', `Aug', `Sep', `Oct', `Nov', and `Dec'.

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

       char * ctime (const time_t *time) 
Ctime функция подобна asctime, за исключением того, что значение времени определено в календарном времени (не местное время). Она эквивалентна asctime (localtime (time)) . ctime устанавливает переменную tzname, потому что так делает localtime. См. Раздел 17.2.6 [Функции Часового пояса].
       size_t strftime (char *s, size_t size, const char *template, const struct tm *brokentime)
Эта функция подобна sprintf функции (см. Раздел 7.11 [Форматируемый Ввод]), но спецификации преобразования, которые могут появляться в шаблоне формата, специализированы для печати компонентов даты и времени brokentime согласно стандарту, в настоящее время заданному для преобразования времени (см. Главу 19 [Стандарты]).

Обычные символы, появляющиеся в шаблоне копируются в строку вывода s; она может включать многобайтовые символы. Спецификаторы Преобразования представляются символом ` % ', и заменяются в строке вывода следующим образом:

Параметр size может использоваться, чтобы определить максимальное число символов, которое будет сохранено в массиве s, включая пустой символ завершения. Если форматируемое время требует больше чем size символов, лишние символы отбрасываются. Возвращаемое значение из strftime - число символов, помещенное в массив s, не включая пустой символ завершения. Если значение равняется размеру, это означает что массив s был слишком мал; Вы должны повторить обращение, обеспечивая больший массив.

Если s - пустой указатель, strftime не делает фактической записи чего-нибудь, но взамен возвращает число символов, которое она написала бы.

Для примера strftime, см. Раздел 17.2.7 [Пример Функции Времени].

Определение Часового пояса с TZ

В системе GNU, пользователь может определять часовой пояс посредством TZ переменной среды.

Для уточнения инфрмации относительно того, как устанавливать переменные среды, см. Раздел 22.2 [Переменные среды]. Функции для доступа к часовому поясу объявлены в " time.h ".

Значение TZ переменной может иметь один из трех форматов. Первый формат используется, когда не имеется никакого Смещения светового дня (или в летнее время) в зоне местного времени:

       std offset
Std строка определяет имя часового пояса. Эта строка должна состоять из трех или большего количества символов и не должно содержать первым символом двоеточие, и цифры, запятые, плюс или минус внутри.

Смещение определяет значение которое нужно добавить к местному времени, чтобы получить значение Координированного Универсального времени. Она имеет синтаксис подобно [+ | -] hh [: mm [: ss]]. Она положительно, если зона местного времени - к западу от Главного меридиана и отрицательно, если она восточнее. Час должен быть от 0 до 24, а минуты и секунды от 0 до 59.

Например, вот, как мы определили бы Восточное Стандартное Время, но без любых Смещений Светового дня:

       EST+5
Второй формат используется, когда имеется Смещение светового дня:
       std offset dst [offset],start[/time],end[/time]
Начальные std и offset определяют стандартный часовой пояс, как описано выше. Dst строка и offset определяет имя и смещение для соответствующего Смещения Дня этого часового пояса; если смещение опущено, это значения по умолчанию равно одному часу перед стандартным временем.

Остаточный член от спецификации описывает, когда смещение светового дня действует. Поле start - то, когда смещение светового дня входит в силу, а поле end - то, когда изменение будет сделано обратно к стандартному времени. Следующие форматы распознаваемы для этих полей: Jn определяет Юлианский день, с n между 1 и 365. 29 февраля никогда не рассчитывается, даже в високосные годы. N определяет Юлианский день, с n между 0 и 365. 29 февраля рассчитан в високосные годы. Mm.w.d определяет день d недели w месяца m. день d должен быть между 0 (воскресеньем) и 6. Неделя w должна быть между 1 и 5; неделя 1 - первая неделя, в которой есть день d , а неделя 5 определяет последний d день в месяце. Месяц m должен быть между 1 и 12.

Поля time определяют, когда, по местному времени происходит изменение к другому времени. Значение по умолчанию - 02:00:00.

Например, вот, как можно определить Восточный часовой пояс в Соединенных Штатах, включая соответствующее смещение светового дня и даты применимости. Нормальное смещение ПО ГРИНВИЧУ - 5 часов; так как это - к западу от главного меридиана, знак положителен. Летний период начинается в первое воскресенье апреля в 2:00am, и кончается в последнее воскресенье октября в 2:00am.

       EST+5EDT,M4.1.0/M10.5.0
План смещения светового дня в любой юрисдикции не изменяется годами.

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

Третий формат походит на:

                 :characters
Каждая операционная система интерпретирует этот формат по­ разному; в библиотеке GNU C, characters - имя файла, который описывает часовой пояс.

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

Функции и Переменные для Часовых поясов

       char * tzname [2]  (переменная)
Массив tzname содержит две строки, которые являются стандартными трех-символьными именами пары часовых поясов (стандартный и смещения светового дня) которые пользователь выбрал. Tzname [0] ­ имя стандартного часового пояса (например, "EST"), а tzname [1] ­ имя для часового пояса, когда смещение светового дня находится в использовании (например, "EDT"). Они соответствуют к std и dst строкам (соответственно) из TZ переменной среды. Tzname массив инициализируется из переменной среды TZ всякий раз, когда tzset, ctime, strftime, mktime, или localtime вызывается.
       void tzset (void) 
Tzset функция инициализирует переменную tzname из значения переменной среды TZ. Обычно вашей программе не нужно вызывать эту функцию, потому что она вызывается автоматически, когда Вы используете другие функции преобразования времени, которые зависят от часового пояса.

Следующие переменные определены для совместимости с System V Unix. Эти переменные устанавливаются вызоввом localtime.

       long int timezone  
Эта переменная содержит различие между временем ПО ГРИНВИЧУ и местным стандартным временем, в секундах. Например, в США в Восточном часовом поясе значение - 5*60*60.
       int daylight  
Эта переменная имеет значение отличное от нуля, если применяются стандартные американские правила смещения светового дня.

Пример Функции Времени

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

                 #include <time.h>
                 #include <stdio.h>
                 #define SIZE 256
                 int
                 main (void)
                 {
                         char buffer[SIZE];
                         time_t curtime;
                         struct tm *loctime;
                         curtime = time (NULL);
                         loctime = localtime (&curtime);
                         fputs (asctime (loctime), stdout);
                         strftime (buffer, SIZE,
         "Today is %A, %B %d.\n", loctime);
                         fputs (buffer, stdout);
                         strftime (buffer, SIZE,
         "The time is %I:%M %p.\n", loctime);
                         fputs (buffer, stdout);
                         return 0;
                 }
Она производит примерно такой вывод:

       Wed Jul 31 13:02:36 1991
       Today is Wednesday, July  31.
       The time is 01:02 PM.

17.3 Установка Сигнализаций

Функции alarm и setitimer обеспечивают механизм прерывания процесса, в некоторое время. Они делают это, устанавливая таймер; когда время таймер истекает, процесс получает сигнал.

Каждый процесс имеет три доступных независимых таймера интервала:

Вы можете иметь только один таймер каждого вида в любое заданное время. Если Вы устанавливаете таймер, который еще не истек, этот таймер будет сброшен в новое значение.

Вы должны установить обработчик для соответствующего сигнала alarm, используюя signal или sigaction перед обращением к setitimer или alarm. Иначе, необычная цепочка событий может заставлить таймер исчерпать время прежде, чем ваша программа установит обработчик, и в этом случае она будет завершена, так как это - заданное по умолчанию действие для сигналов alarm. См. Главу 21 [Обработка Сигнала].

Функция setitimer - первичный способ для установки будильника. Это средство объявлено в заглавном файле " sys/time.h ". Функция alarm, объявленная в " unistd.h ", обеспечивает несколько более простой интерфейс для установки таймера в реальном времени.

       struct itimerval  (тип данных)
Эта структура используется, чтобы определить, когда таймер должен истечь. Она содержит следующие элементы:
       struct timeval it_interval
Это - интервал между последовательными прерываниями по таймеру. Значение - нуль, если сигнал будет только послан один раз.
       struct timeval it_value
Это - интервал до первого прерывания по таймеру. Значение - нуль если, он заблокирован.

Тип данных Struct timeval описан в Разделе 17.2.2 [Календарь с высоким разрешением].

       int setitimer (int which, struct itimerval *old, struct itimerval *new)
Функция setitimer устанавливает таймер, заданный как which согласно new. Аргумент which может иметь значение ITIMER_REAL, ITIMER_VIRTUAL, или ITIMER_PROF.

Если old - не пустой указатель, setitimer возвращает информацию относительно любого предыдущего неистекшего таймера того же самого вида в структуре, на которую он указывает.

Возвращаемое значение - 0 при успехе и -1 при отказе. Следующие errno условия ошибки определены для этой функции:

EINVAL

интервал таймера был слишком большой.

       int getitimer (int which, struct itimerval *old)
Getitimer функция сохраняет информацию относительно таймера, заданного which в структуре, указанной в old.

Возвращаемое значение и условия ошибки - такие же как для setitimer.

       ITIMER_REAL
Эта константа может использоваться как аргумент which для setitimer и getitimer функций, чтобы определить таймер в реальном времени.
       ITIMER_VIRTUAL
Эта константа может использоваться как аргумент which для setitimer и getitimer, чтобы определить виртуальный таймер.
       ITIMER_PROF
Эта константа может использоваться как аргумент which для setitimer и getitimer, чтобы определить таймер профилирования.
       unsigned int alarm (unsigned int seconds) 
Функция alarm устанавливает таймер в реальном времени, с периодом в second секунд. Если Вы хотите отменить любой существующий таймер, Вы может сделать это, вызывая alarm с аргументом 0.

Возвращаемое значение указывает, сколько секунд оставалось прежде, чем предыдущий сигнал был бы послан. Если не было никакого предыдущего сигнала, alarm возвращает нуль.

Функция alarm могла бы быть определена в терминах setitimer примерно так:

                 unsigned int
                 alarm (unsigned int seconds)
                 {
                         struct itimerval old, new;
                         new.it_interval.tv_usec = 0;
                         new.it_interval.tv_sec = 0;
                         new.it_value.tv_usec = 0;
                         new.it_value.tv_sec = (long int) seconds;
                         if (setitimer (ITIMER_REAL, &new, &old) < 0)
                                 return 0;
                         else
                                 return old.it_value.tv_sec;
                 }
Имеется пример, показывающий использование функции alarm в Разделе 21.4.1 [Возврат Обработчика].

Если Вы просто хотите, чтобы ваш процесс ждал данное число секунд, Вы должен использовать функцию sleep. См. Раздел 17.4 [Sleep].

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

Примечание Переносимости: setitimer и getitimer - функции UNIX BSD, в то время как функция alarm определена POSIX.1 стандартом. Setitimer более мощная чем alarm, но alarm более широко используется.

17.4 Sleep

Sleep дает простой способ заставить программу ждать некоторый период времени. Если ваша программа не использует сигналы (за исключением завершения), то Вы можете расчитывать, что sleep будет ждать заданное количество времени. Иначе, sleep может возвращаться, если прибывает сигнал; если Вы хотите ждать данный период независимо от сигналов, используйте select (см. Раздел 8.6 [Ждущий ввод - вывод] ) и не определяйте ни каких описателей ожидания.

       unsigned int sleep (unsigned int seconds) 
Функция sleep ждет seconds секунд или пока не получен сигнал.

Если функция sleep возвращает значение по истечении времени, то это значение нуль. Если она возвращается после сигнала, возвращаемое значение - остающееся время ожидания sleep.

Функция sleep объявлена в " unistd.h ".

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

17.5 Использование Ресурсов

Функция getrusage и тип данных struct rusage используется для исследования типа использования процесса. Они объявлены в " sys/resource.h ".

       int getrusage (int processes, struct rusage *rusage) 
Эта функция сообщает общее использование для процессов, заданных в processes, сохраняя информацию в *rusage.

В большинстве систем, processes имеет только два допустимых значения:

       RUSAGE_SELF
Только текущий процесс.
       RUSAGE_CHILDREN
Все дочерние процессы (прямые и косвенные) которые уже завершились.

В системе GNU, Вы можете также запрашивать относительно специфического дочернего процесса, определяя ID процесса.

Возвращаемое значение getrusage - нуль при успехе, и -1 при отказе.

Аргумент EINVAL processes не допустим.

Еще один способ получения типа использования для специфического дочернего процесса - функцией wait4, которая возвращает общие количества для дочернего процесса при его завершении. См. Раздел 23.8 [BSD Функции Ожидания].

       struct rusage
Этот тип данных записывает величину использования различного рода ресурсов. Он имеет следующие элементы (возможны другие):
       struct timeval ru_utime
Использованное пользовательское время.
       struct timeval ru_stime
Использованное системное время.
       long ru_majflt
Число страниц.
       long ru_inblock
Число блокировок операций ввода.
       long ru_oublock
Число блокировок операций вывода.
       long ru_msgsnd
Число посланных сообщений.
       long ru_msgrcv
Число полученных сообщений.
       long ru_nsignals
Число полученных сигналов.

Дополнительная историческая функция для исследования типов использования, vtimes, обеспечивается но здесь не описана. Она объявлена в " sys/vtimes.h ".

17.6 Ограничение Использования Ресурсов

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

Символы в этом разделе определены в " sys/resource.h ".

       int getrlimit (int resource, struct rlimit *rlp)  (функция)
Читает текущее значение и максимальное значение ресурса resource, и сохраняет их в *rlp.

Возвращаемое значение - 0 при успехе и -1 при отказе. Единственое возможное errno условие ошибки - EFAULT.

       int setrlimit (int resource, struct rlimit *rlp)  (функция)
Сохраняет текущее значение и максимальное значение ресурса в *rlp.

Возвращаемое значение - 0 при успехе и -1 при отказе. Следующее errno условие ошибки возможно:

EPERM

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

       struct rlimit  (тип данных)
Эта структура используется с getrlimit, чтобы получить значения ограничений, и с setrlimit, чтобы определить значения ограничений. Она имеет два поля:

Rlim_cur Текущее значение рассматриваемого ограничения.

Rlim_max Максимально допустимое значение рассматриваемого ограничения. Вы не можете устанавливать текущее значение ограничения больше чем этот максимум. Только root может изменять максимально допустимое значение.

В getrlimit, эта структура - вывод; она получает текущие значения. В setrlimit она определяет новые значения.

Вот список ресурсов, для которых Вы можете определять ограничения.

       RLIMIT_CPU
Максимальное количество времени центрального процессора которое процесс может использовать. Если он выполняется дольше чем это время, он получает сигнал: SIGXCPU. Значение измеряется в секундах. См. Раздел 21.2.7 [Нестандартные Сигналы].
       RLIMIT_FSIZE
Максимальный размер файла котоый процесс может создать. При попытке записать больший файл вызывается сигнал: SIGXFSZ. См. Раздел 21.2.7 [Нестандартные Сигналы].
       RLIMIT_DATA
Максимальный размер памяти данных для процесса. Если процесс пробует зарезервировать память больше этого количества, функции резервирования выдает ошибку.
       RLIMIT_STACK
Максимальный размер стека для процесса. Если процесс пробует расширять стек больше этого размера, он получает сигнал SIGSEGV. См. Раздел 21.2.1 [Сигналы Ошибки в программе].
       RLIMIT_CORE
Максимальный размер core-файла, который этот процесс может создавать. Если процесс завершается и этот максимальный размер не достаточен для core-файла, файл будет усечен.
       RLIMIT_RSS
Максимальное количество физической памяти, которое этот процесс может получить. Этот параметр - руководство для планировщика системы и программы распределения памяти; система может давать процессу большее количество памяти, когда имеется излишек.
       RLIMIT_OPEN_FILES
Максимальное число файлов, которые процесс может открывать. Если он пробует открывать большее количество файлов, он получает код ошибки EMFILE. См. Раздел 2.2 [Коды Ошибки].
       RLIM_NLIMITS
Число различных ограничений ресурсов. Любой допустимый операнд ресурса должен быть меньше чем RLIM_NLIMITS.
       int RLIM_INFINITY  
Эта константа замещает значение "бесконечности" когда обеспечивается как значение ограничения в setrlimit.

Две исторических функции для установки ограничений ресурса, ulimit и vlimit, не зарегистрированы здесь. Они объявлены в " sys/vlimit.h " и исходят ИЗ BSD.

17.7 Приоритет Процесса

Когда отдельные процессы выполняются, их приоритеты определяют то, какую часть ресурсов CPU каждый процесс получает. Этот раздел описывает, как Вы можете читать и устанавливать приоритет процесса. Все эти функции и макрокоманды объявлены в " sys/resource.h ".

Промежуток допустимых значений зависит от операционной системы, но обычно он выполняется от -20 до 20. Меньшее значение приоритета означает что процесс выполняет чаще. Эти константы описывают некоторые значения: PRIO_MIN самое маленькое допустимое значение приоритета. PRIO_MAX самое большое допустимое значение приоритета.

       int getpriority (int class, int id)  (функция)
Читает приоритет класса процессов, задаваемого class и id (см. ниже).

Возвращаемое значение - значение приоритета при успехе, и -1 при отказе. Следующее errno условие ошибки возможно для этой функции:

ESRCH

комбинация class и id не соответствует никакому существующему процессу.

EINVAL

значение class не допустимо.

Когда возвращаемое значение -1, это может указывать отказ, или значение приоритета.

Единственый способ различить состоит в том, чтобы установить errno = 0 перед вызовом getpriority, и тогда использовать errno!= 0 позже как критерий для отказа.

       int setpriority (int class, int id, int priority)  (функция)
Устанавливает приоритет класса процессов, задаваемого class и id (см. ниже).

Возвращаемое значение - 0 при успехе и -1 при отказе. Следующее errno условие ошибки определено для этой функции:

ESRCH

комбинация class и id не соответствует никакому существующему процессу.

EINVAL

значение класса не допустимо.

EPERM

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

EACCES

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

Аргументы class и id вместе определяет набор процессов, которыми Вы заинтересованы. Вот возможные значения для class:
       PRIO_PROCESS
Читает или устанавливает приоритет одного процесса. id аргумент - ID процесс.
       PRIO_PGRP
Читает или устанавливает приоритет одной группы процесса. Аргумент id - ID группы процесса.
       PRIO_USER
Читает или устанавливает приоритет процессов одного пользователя. Аргумента id - ID пользователя.

Если id аргумент - 0, то обрабатывается текущий процесс, текущая группа процесса, или текущий пользователь, согласно классу.

       int nice (int increment)  (функция)
Увеличьте приоритет текущего процесса приращением. Возвращаемое значение не важно.

Вот эквивалентное определение для nice:

                 int
                 nice (int increment)
                 {
                         int old = getpriority (PRIO_PROCESS, 0);
                         setpriority (PRIO_PROCESS,0,old+increment);
                 }

Next Previous Contents