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

T2

.c
Скачиваний:
18
Добавлен:
19.06.2023
Размер:
5.22 Кб
Скачать
/*
 * Выполнил: —, 93—
 * Задание: 2 Вызов лифта
 * Дата выполнения: 16 марта 2023 г.
 * Версия: 0.1
 *
 * Скрипт для компиляции и запуска программы:
 *     cc T2.c -o T2
 *     ./T2
 */
// ------------------------------------------- //
/*
 * Общее описание программы:
 *      Запускается поток, который циклически считывает символы
 *      консоли и отправляет сигналы реального времени для
 *      изменения состояния лифта.
 */
// ------------------------------------------- //


#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>

// Состояния лифта
#define TOP          1
#define THIS_FLOOR   0
#define BOTTOM      -1

// Сигналы реального времени
#define SIG_UP      48
#define SIG_DOWN    49

int state = THIS_FLOOR;
sigset_t sigset;

void print_state() {
    switch (state) {
        case THIS_FLOOR:
            printf("state THIS_FLOOR\n");
            break;
        case TOP:
            printf("state TOP\n");
            break;
        case BOTTOM:
            printf("state BOTTOM\n");
            break;
    }
}

// Задержка после прибытия лифта на этаж вызова
void open() {
    printf("This floor, door is opened\n");
    sleep(1);
}

// Движение лифта вверх, изменение состояния на новое
void move_up(int new_state) {
    for (int i = 1; i <= 3; i++) {
        printf("*** Go UP\n");
        usleep(500000);
    }
    state = new_state;
    print_state();
}

// Движение лифта вниз, изменение состояния на новое
void move_down(int new_state) {
    for (int i = 1; i <= 3; i++) {
        printf("*** Go DOWN\n");
        usleep(500000);
    }
    state = new_state;
    print_state();
}

// Обработчик сигналов движения лифта
void lift_control(int signo, siginfo_t *info, void *nk) {
    switch (state) {
        case THIS_FLOOR:
            if (signo == SIG_UP) {
                open();
                move_up(TOP);
            }
            if (signo == SIG_DOWN) {
                open();
                move_down(BOTTOM);
            }
            break;
        case TOP:
            if (signo == SIG_UP) {
                move_down(THIS_FLOOR);
                open();
                move_up(TOP);
            }
            if (signo == SIG_DOWN) {
                move_down(THIS_FLOOR);
                open();
                move_down(BOTTOM);
            }
            break;
        case BOTTOM:
            if (signo == SIG_UP) {
                move_up(THIS_FLOOR);
                open();
                move_up(TOP);
            }
            if (signo == SIG_DOWN) {
                move_up(THIS_FLOOR);
                open();
                move_down(BOTTOM);
            }
            break;
    }
    printf("---\n");
}


// Обработчик нажатия кнопки
void *push_button(void *args) {
    // Привязка обработчиков к сигналам
    struct sigaction act;
    act.sa_sigaction = lift_control;
    act.sa_flags = SA_SIGINFO;
    act.sa_mask = sigset;
    sigaction(SIG_UP, &act, NULL);
    sigaction(SIG_DOWN, &act, NULL);

    // Считывание символов из консоли и отправка сигналов
    char ch = 0;
    while (ch != 'q') {
        ch = getchar();
        switch (ch) {
            case 'u':
                printf("Sending SIG_UP\n");
                raise(SIG_UP);
                break;
            case 'd':
                printf("Sending SIG_DOWN\n");
                raise(SIG_DOWN);
                break;
            case 'q':
                printf("Stopping\n");
                break;
        }
    }
    return EXIT_SUCCESS;
}

int main(int argc, char *argv[]) {
    printf("Start\n");

    // Инициализация маски сигналов
    sigemptyset(&sigset);
    sigaddset(&sigset, SIG_UP);
    sigaddset(&sigset, SIG_DOWN);

    // Запуск потока обработчика нажатия кнопки
    pthread_t button_thread;
    pthread_create(&button_thread, NULL, &push_button, NULL);
    pthread_join(button_thread, NULL);

    printf("Finish\n");
    return EXIT_SUCCESS;
}

// ----------------------------------------//
/*
Start
uudq
Sending SIG_UP
This floor, door is opened
*** Go UP
*** Go UP
*** Go UP
state TOP
---
Sending SIG_UP
*** Go DOWN
*** Go DOWN
*** Go DOWN
state THIS_FLOOR
This floor, door is opened
*** Go UP
*** Go UP
*** Go UP
state TOP
---
Sending SIG_DOWN
*** Go DOWN
*** Go DOWN
*** Go DOWN
state THIS_FLOOR
This floor, door is opened
*** Go DOWN
*** Go DOWN
*** Go DOWN
state BOTTOM
---
Stopping
Finish

Process finished with exit code 0
*/
Соседние файлы в предмете Системы реального времени