Администрирование локальных сетей
Категория реферата: Рефераты по информатике, программированию
Теги реферата: реферат по культурологии, доклад по биологии
Добавил(а) на сайт: Tolkachjov.
Предыдущая страница реферата | 11 12 13 14 15 16 17 18 19 20 21 | Следующая страница реферата
/* Засечь время момента старта процесса */ 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, которая задержит выполнение программы, пока с клавиатуры не будет введена
строка. Большинство ожиданий внутри системных вызовов - синхронны. Ядро ОС
выступает для программ пользователей в роли сервера, выполняющего сисвызовы
(хотя и не только в этой роли - ядро иногда предпринимает и активные
действия: передача процессора другому процессу через определенное время
(режим разделения времени), убивание процесса при ошибке, и.т.п.).
Сигналы - это асинхронные события. Они приходят неожиданно, в любой момент
времени - вроде телефонного звонка. Кроме того, их не требуется заказывать
- сигнал процессу может поступить совсем без повода. Аналогия из жизни
такова: человек сидит и пишет письмо. Вдруг его окликают посреди фразы - он
отвлекается, отвечает на вопрос, и вновь продолжает прерванное занятие.
Человек не ожидал этого оклика (быть может, он готов к нему, но он не
озирался по сторонам специально). Кроме того, сигнал мог поступить когда он
писал 5-ое предложение, а мог - когда 34-ое. Момент времени, в который
произойдет прерывание, не фиксирован.
Сигналы имеют номера, причем их количество ограничено - есть определенный
список допустимых сигналов. Номера и мнемонические имена сигналов
перечислены в includeфайле и имеют вид SIGнечто. Допустимы
сигналы с номерами 1..NSIG-1, где NSIG определено в этом файле. При
получении сигнала мы узнаем его номер, но не узнаем никакой иной
информации: ни от кого поступил сигнал, ни что от нас хотят. Просто "звонит
телефон". Чтобы получить дополнительную информацию, наш процесс должен
взять ее из другого известного места; например - прочесть заказ из
некоторого файла, об имени которого все наши программы заранее
"договорились". Сигналы процессу могут поступать тремя путями:
От другого процесса, который явно посылает его нам вызовом kill(pid, sig); где pid - идентификатор (номер) процесса-получателя, а sig - номер сигнала. Послать сигнал можно только родственному процессу - запущенному тем же пользователем.
От операционной системы. Система может посылать процессу ряд сигналов, сигнализирующих об ошибках, например при обращении программы по
несуществующему адресу или при ошибочном номере системного вызова. Такие
сигналы обычно прекращают наш процесс.
От пользователя - с клавиатуры терминала можно нажимом некоторых клавиш
послать сигналы SIGINT и SIGQUIT. Собственно, сигнал посылается драйвером
терминала при получении им с клавиатуры определенных символов. Так можно
прервать зациклившуюся или надоевшую программу.
Процесс-получатель должен как-то отреагировать на сигнал. Программа может:
проигнорировать сигнал (не ответить на звонок);
перехватить сигнал (снять трубку), выполнить какие-то действия, затем
продолжить прерванное занятие;
быть убитой сигналом (звонок был подкреплен броском гранаты в окно);
В большинстве случаев сигнал по умолчанию убивает процесс-получатель.
Однако процесс может изменить это умолчание и задать свою реакцию явно. Это
делается вызовом signal:
#include void (*signal(int sig, void (*react)() )) ();
Параметр react может иметь значение:
SIG_IGN сигнал sig будет отныне игнорироваться. Некоторые сигналы (например
SIGKILL) невозможно перехватить или проигнорировать.
SIG_DFL восстановить реакцию по умолчанию (обычно - смерть получателя). имя_функции Например void fr(gotsig){ ..... } /* обработчик */
... signal (sig, fr); ... /* задание реакции */
Рекомендуем скачать другие рефераты по теме: бесплатные тесты бесплатно, рефераты по медицине.
Предыдущая страница реферата | 11 12 13 14 15 16 17 18 19 20 21 | Следующая страница реферата