Добавил:
Вуз:
Предмет:
Файл:
practic1
.c#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <setjmp.h>
#define TP 1000000L // 1 sec
#define NOMINAL_T 500000L // 0.5 sec
#define SOFT_DL 520000L // 0.52 sec
#define HARD_DL 1000000L // 1 sec
static volatile sig_atomic_t soft_deadline_count = 0;
static jmp_buf env;
static volatile sig_atomic_t can_jump = 0;
void soft_handler(int sig) {
(void)sig;
soft_deadline_count++;
char buf[128];
int len = snprintf(buf, sizeof(buf),
"#### Нарушение ограничения № %d ####\n",
soft_deadline_count);
write(STDERR_FILENO, buf, len);
}
void alarm_handler(int sig) {
(void)sig;
const char msg[] = "#####-- Аварийная ситуация, требуется рестарт! --#####\n";
write(STDERR_FILENO, msg, sizeof(msg) - 1);
kill(getpid(), SIGUSR1);
}
void usr1_handler(int sig) {
(void)sig;
if (can_jump) {
can_jump = 0;
longjmp(env, 1);
}
}
void doControl(void) {
int dt = rand() % 70000; // добавка от 0 до 69999 мкс (чтобы перекрыть SOFT_DL)
long work_time = NOMINAL_T + dt; // планируемое время работы в мкс
int stopRun = rand() % 10; // авария с вероятностью 10% (stopRun == 1)
printf("########## t=%ld, dt==%d, stopRun=%d\n", work_time, dt, stopRun);
if (stopRun == 1) {
while (1) {
}
} else {
usleep(work_time);
}
}
void waitMoment(long delay_us) {
struct timespec req, rem;
req.tv_sec = delay_us / 1000000L;
req.tv_nsec = (delay_us % 1000000L) * 1000L;
while (nanosleep(&req, &rem) == -1 && errno == EINTR) {
req = rem;
}
}
int main(void) {
srand((unsigned int)time(NULL));
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = soft_handler;
if (sigaction(SIGRTMIN, &sa, NULL) == -1) {
perror("sigaction SIGRTMIN");
exit(EXIT_FAILURE);
}
sa.sa_handler = alarm_handler;
if (sigaction(SIGALRM, &sa, NULL) == -1) {
perror("sigaction SIGALRM");
exit(EXIT_FAILURE);
}
sa.sa_handler = usr1_handler;
if (sigaction(SIGUSR1, &sa, NULL) == -1) {
perror("sigaction SIGUSR1");
exit(EXIT_FAILURE);
}
if (setjmp(env) == 0) {
can_jump = 1;
} else {
printf("Программа завершена по аварийному сигналу.\n");
return 1;
}
int loop_counter = 0;
while (1) {
loop_counter++;
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);
alarm(0);
alarm(1);
doControl();
alarm(0);
clock_gettime(CLOCK_MONOTONIC, &end);
long elapsed_us = (end.tv_sec - start.tv_sec) * 1000000L +
(end.tv_nsec - start.tv_nsec) / 1000L;
printf("### Фактическое время работы %ld ###\n", elapsed_us);
if (elapsed_us > SOFT_DL) {
raise(SIGRTMIN);
}
long delay_us = TP - elapsed_us;
if (delay_us > 0) {
waitMoment(delay_us);
} else {
printf("Предупреждение: время работы превысило период! Задержка отрицательная.\n");
}
}
return 0;
}
/*
########## t=568087, dt==68087, stopRun=7
### Фактическое время работы 573711 ###
#### Нарушение ограничения № 1 ####
########## t=506750, dt==6750, stopRun=6
### Фактическое время работы 507112 ###
########## t=565273, dt==65273, stopRun=3
### Фактическое время работы 565709 ###
#### Нарушение ограничения № 2 ####
########## t=503351, dt==3351, stopRun=4
### Фактическое время работы 508276 ###
########## t=515702, dt==15702, stopRun=7
### Фактическое время работы 518755 ###
########## t=551192, dt==51192, stopRun=8
### Фактическое время работы 553744 ###
#### Нарушение ограничения № 3 ####
########## t=537990, dt==37990, stopRun=1
#####-- Аварийная ситуация, требуется рестарт! --#####
Программа завершена по аварийному сигналу.
*/
Соседние файлы в предмете Системы реального времени
