Добавил:
jetu
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:T1
.c/*
* Выполнил: —, 93—
* Задание: 1 Обеспечение таймаута
* Дата выполнения: 11 марта 2023 г.
* Версия: 0.1
*
* Скрипт для компиляции и запуска программы:
* cc T1.c -o T1
* ./T1
*/
// ------------------------------------------- //
/*
* Общее описание программы:
* Циклически выполняется функция со случайной задержкой
* и вероятностью «зависнуть» 1/6. Если функция выполняется
* более 0,52 секунд, посылается сигнал SIGUSR2, обработчик
* которого выводит сообщение о превышении «мягкого» лимита.
* При обнаружении «зависания» рабочей функции происходит
* обработка сигнала SIGALRM, при котором система прекращает
* работу, посылая сигнал SIGUSR1.
*/
// ------------------------------------------- //
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
// Возвращает случайное вещественное число от 0 до 1
double r() {
return (double) rand() / (double) RAND_MAX;
}
// Привязывает обработчик к сигналу
void handle(int sig, __sighandler_t handler) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, sig);
struct sigaction act;
act.sa_handler = handler;
act.sa_flags = 0;
act.sa_mask = set;
sigaction(sig, &act, NULL);
}
// Обработчик сигнала на превышение времени работы
static void deadlineHandler(int sig) {
printf("#### Deadline exceeded ####\n");
}
// Обработчик SIGALRM
static void alarmHandler(int sig) {
printf("«#####-- Restart requered! --#####\n");
// прекращение работы с отправкой сигнала SIGUSR1
exit(SIGUSR1);
}
// Рабочая функция
void doControl() {
// задание случайной задержки от 0,5 до 0,51 секунд
int t = 500000 + r() * 10000;
printf("########## %d\n", t);
// «зависание» программы с вероятностью 1/6
int x = r() * 6;
if (x == 0) while(1);
// основная «работа» функции
usleep(t);
}
int main() {
int deadlineSig = SIGUSR2;
// Привязка обработчиков
handle(deadlineSig, deadlineHandler);
handle(SIGALRM, alarmHandler);
struct timeval t0;
struct timeval t1;
double a;
double t;
// Управляющий цикл
while (1) {
// отправка SIGALRM через 1 секунду
alarm(1);
// сохранение времени до работы функции
gettimeofday(&t0, NULL);
// выполнение рабочей функции
doControl();
// сохранение времени после работы функции
gettimeofday(&t1, NULL);
// отмена отправки SIGALRM
a = (double) ualarm(0, 0);
// вывод оставшегося времени до SIGALRM
printf("\tAlarm time left: %f\n", a / 1000000);
// вывод затраченного времени на выполнение рабочей функции
t = (double) (t1.tv_sec - t0.tv_sec) * 1000 + (double) (t1.tv_usec - t0.tv_usec) / 1000;
printf("\tTime taken: %f\n", t / 1000);
// проверка на превышение «мягкого» лимита
if (t > 500 * 1.04) raise(deadlineSig);
// задержка перед следующей итерацией цикла
sleep(3);
}
}
// ----------------------------------------//
/*
########## 508401
Alarm time left: 0.478060
Time taken: 0.521920
#### Deadline exceeded ####
########## 507830
Alarm time left: 0.463584
Time taken: 0.536397
#### Deadline exceeded ####
########## 509116
Alarm time left: 0.490632
Time taken: 0.509363
########## 503352
Alarm time left: 0.491254
Time taken: 0.508741
########## 502777
Alarm time left: 0.496459
Time taken: 0.503538
########## 504773
Alarm time left: 0.481889
Time taken: 0.518107
########## 503647
Alarm time left: 0.485325
Time taken: 0.514673
########## 509522
Alarm time left: 0.473874
Time taken: 0.526095
#### Deadline exceeded ####
########## 506357
Alarm time left: 0.493012
Time taken: 0.506983
########## 501416
Alarm time left: 0.496633
Time taken: 0.503365
########## 500163
Alarm time left: 0.499765
Time taken: 0.500232
########## 501372
Alarm time left: 0.474580
Time taken: 0.525415
#### Deadline exceeded ####
########## 501566
Alarm time left: 0.399636
Time taken: 0.600359
#### Deadline exceeded ####
########## 501297
«#####-- Restart requered! --#####
Process finished with exit code 10
*/