Администрирование локальных сетей
Рефераты >> Программирование и компьютеры >> Администрирование локальных сетей

tm_mday дата месяца 1 31

tm_wday день недели 0 6 (0 - Воскресенье)

tm_hour часы 0 23

tm_min минуты 0 59

tm_sec секунды 0 59

Номера месяца и дня недели начинаются с нуля, чтобы вы могли использовать их в качестве индексов:

char *months[] = { "Январь", "Февраль", ., "Декабрь" };

printf( "%s\n", months[ tm->tm_mon ] );

Часто бывает нужда передавать значения времени в одной строке

Вот пример программы которая преобразовывает в ремя в такой формат:

/* Mon Jun 12 14:31:26 2000 */

#include <stdio.h>

#include <time.h>

main() { /* команда date */

time_t t = time(NULL);

char *s = ctime(&t);

printf("%s", s);

}

UNIX-машины имеют встроенные таймеры (как правило несколько) с довольно высоким разрешением. Некоторые из них могут использоваться как "будильники" с обратным отсчетом времени: в таймер загружается некоторое значение; таймер ведет обратный отсчет, уменьшая загруженный счетчик; как только это время истекает - посылается сигнал процессу, загрузившему таймер.

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

#include <sys/types.h>

#include <signal.h>

#include <sys/time.h>

void do_nothing() {}

/* Задержка на usec миллионных долей секунды (микросекунд) */

void usleep(unsigned int usec) {

struct itimerval new, old;

/* struct itimerval содержит поля:

struct timeval it_interval;

struct timeval it_value;

Где struct timeval содержит поля:

long tv_sec; -- число целых секунд

long tv_usec; -- число микросекунд

*/

struct sigaction new_vec, old_vec;

if (usec == 0) return;

/* Поле tv_sec содержит число целых секунд.

Поле tv_usec содержит число микросекунд.

it_value - это время, через которое В ПЕРВЫЙ раз

таймер "прозвонит",

то есть пошлет нашему процессу

сигнал SIGALRM.

Время, равное нулю, немедленно остановит таймер.

it_interval - это интервал времени, который будет загружаться

в таймер после каждого "звонка"

(но не в первый раз).

Время, равное нулю, остановит таймер

после его первого "звонка".

*/

new.it_interval.tv_sec = 0;

new.it_interval.tv_usec = 0;

new.it_value.tv_sec = usec / 1000000;

new.it_value.tv_usec = usec % 1000000;

/* Сохраняем прежнюю реакцию на сигнал SIGALRM в old_vec,

заносим в качестве новой реакции do_nothing()

*/

new_vec.sa_handler = do_nothing;

sigemptyset(&new_vec.sa_mask);

new_vec.sa_flags = 0;

sigaction(SIGALRM, &new_vec, &old_vec);

/* Загрузка интервального таймера значением new, начало отсчета.

* Прежнее значение спасти в old.

* Вместо &old можно также NULL - не спасать.

*/

setitimer(ITIMER_REAL, &new, &old);

/* Ждать прихода сигнала SIGALRM */

sigpause(SIGALRM);

/* Восстановить реакцию на SIGALRM */

sigaction(SIGALRM, &old_vec, (struct sigaction *) 0);

sigrelse(SIGALRM);

/* Восстановить прежние параметры таймера */

setitimer(ITIMER_REAL, &old, (struct itimerval *) 0);

}

Пример оспользования интервалов

#include <stdio.h>

#include <unistd.h> /* _SC_CLK_TCK */

#include <signal.h> /* SIGALRM */

#include <sys/time.h> /* не используется */

#include <sys/times.h> /* struct tms */

struct tms tms_stop, tms_start;

clock_t real_stop, real_start;

clock_t HZ; /* число ticks в секунде */

/* Засечь время момента старта процесса */

void hello(void){

real_start = times(&tms_start);

}

/* Засечь время окончания процесса */

void bye(int n){

real_stop = times(&tms_stop);

#ifdef CRONO

/* Разность времен */

tms_stop.tms_utime -= tms_start.tms_utime;

tms_stop.tms_stime -= tms_start.tms_stime;

#endif

/* Распечатать времена */

printf("User time = %g seconds [%lu ticks]\n",

tms_stop.tms_utime / (double)HZ, tms_stop.tms_utime);

printf("System time = %g seconds [%lu ticks]\n",

tms_stop.tms_stime / (double)HZ, tms_stop.tms_stime);

printf("Children user time = %g seconds [%lu ticks]\n",

tms_stop.tms_cutime / (double)HZ, tms_stop.tms_cutime);

printf("Children system time = %g seconds [%lu ticks]\n",

tms_stop.tms_cstime / (double)HZ, tms_stop.tms_cstime);

printf("Real time = %g seconds [%lu ticks]\n",

(real_stop - real_start) / (double)HZ, real_stop - real_start);

exit(n);

}

/* По сигналу SIGALRM - завершить процесс */

void onalarm(int nsig){

printf("Выход #%d ================\n", getpid());

bye(0);

}

/* Порожденный процесс */

void dochild(int n){

hello();

printf("Старт #%d ================\n", getpid());

signal(SIGALRM, onalarm);

/* Заказать сигнал SIGALRM через 1 + n*3 секунд */

alarm(1 + n*3);

for(;;){} /* зациклиться в user mode */

}

#define NCHLD 4

int main(int ac, char *av[]){

int i;

/* Узнать число тиков в секунде */

HZ = sysconf(_SC_CLK_TCK);

setbuf(stdout, NULL);

hello();

for(i=0; i < NCHLD; i++)

if(fork() == 0)

dochild(i);

while(wait(NULL) > 0);

printf("Выход MAIN =================\n");

bye(0);

return 0;

}

Сигналы.

Процессы в UNIX используют много разных механизмов взаимодействия. Одним из них являются сигналы.

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

Схема с синхронными событиями очень распространена. Кассир сидит у кассы и ожидает, пока к нему в окошечко не заглянет клиент. Поезд периодически проезжает мимо светофора и останавливается, если горит красный. Функция Си пассивно "спит" до тех пор, пока ее не вызовут; однако она всегда готова выполнить свою работу (обслужить клиента). Такое ожидающее заказа (события) действующее лицо называется сервер. После выполнения заказа сервер вновь переходит в состояние ожидания вызова. Итак, если событие ожидается в специальном месте и в определенные моменты времени (издается некий вызов для ОПРОСА) - это синхронные события. Канонический пример - функция gets, которая задержит выполнение программы, пока с клавиатуры не будет введена строка. Большинство ожиданий внутри системных вызовов - синхронны. Ядро ОС выступает для программ пользователей в роли сервера, выполняющего сисвызовы (хотя и не только в этой роли - ядро иногда предпринимает и активные действия: передача процессора другому процессу через определенное время (режим разделения времени), убивание процесса при ошибке, и.т.п.).


Страница: