Добавил:
north memphis Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

practic1

.c
Скачиваний:
0
Добавлен:
17.07.2026
Размер:
5 Кб
Скачать
#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
#####-- Аварийная ситуация, требуется рестарт! --#####
Программа завершена по аварийному сигналу.
*/
Соседние файлы в предмете Системы реального времени