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

4 / T4_Kharitonov_1374

.c
Скачиваний:
0
Добавлен:
09.11.2025
Размер:
6.56 Кб
Скачать
/*
 Выполнил: Харитонов Алексей, гр. 1374
 Задание: Вызов лифта
 Дата выполнения: 21 марта 2025
 */

/*
 Описание программы:
 Программа моделирует работу автомата управления лифтом при его вызове с этажа.
 На панели расположены две кнопки: «Вверх» (u) и «Вниз» (d). При нажатии на кнопку
 посылается соответствующий сигнал реального времени (Up или Down), который обрабатывается
 обработчиком сигналов lift_control. В зависимости от текущего состояния лифта (TOP, THIS_FLOOR, BOTTOM)
 происходит выполнение определённой последовательности действий (движение лифта, открытие двери).
 После прибытия лифта на этаж вызова осуществляется задержка в 1 секунду, а затем лифт продолжает движение.
 */
 
/*
 Скрипт для компиляции и запуска программы:
 Сборка: gcc T4_Kharitonov_1374.c -o T4_Kharitonov_1374 -pthread
 Запуск: ./T4_Kharitonov_1374
 */

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

// Определение состояний лифта
#define TOP         0   // лифт вверху
#define BOTTOM      1   // лифт внизу
#define THIS_FLOOR  2   // лифт на нашем этаже

// Определение сигналов реального времени
#define Up          48  
#define Down        49  

// Глобальная переменная, определяющая текущее состояние лифта
volatile int state = THIS_FLOOR;

// Функция, имитирующая движение лифта
void move(int direction) {
    int i, n = 3;
    if(direction == Up) {
        for(i = 1; i <= n; i++){
            printf("*** Go UP\n");
            usleep(500000);  // задержка 0.5 сек
        }
    } else if(direction == Down) {
        for(i = 1; i <= n; i++){
            printf("*** Go DOWN\n");
            usleep(500000);
        }
    }
}

// Обработчик сигналов для управления лифтом
void lift_control(int signo, siginfo_t* info, void* context) {
    printf("Received signal: %d in state: %d\n", signo, state);
    switch(state) {
        case THIS_FLOOR:
            if(signo == Up) {
                printf("This Floor, door is opened\n");
                sleep(1);
                move(Up);
                state = TOP;
                printf("Elevator reached TOP\n");
            } else if(signo == Down) {
                printf("This Floor, door is opened\n");
                sleep(1);
                move(Down);
                state = BOTTOM;
                printf("Elevator reached BOTTOM\n");
            }
            break;
        case TOP:
            if(signo == Up) {
                move(Down);
                printf("This Floor, door is opened\n");
                sleep(1);
                move(Up);
                state = TOP;
                printf("Elevator returned to TOP\n");
            } else if(signo == Down) {
                move(Down);
                printf("This Floor, door is opened\n");
                sleep(1);
                move(Down);
                state = BOTTOM;f
                printf("Elevator reached BOTTOM\n");
            }
            break;
        case BOTTOM:
            if(signo == Up) {
                move(Up);
                printf("This Floor, door is opened\n");
                sleep(1);
                move(Up);
                state = TOP;
                printf("Elevator reached TOP\n");
            } else if(signo == Down) {
                move(Up);
                printf("This Floor, door is opened\n");
                sleep(1);
                move(Down);
                state = BOTTOM;
                printf("Elevator returned to BOTTOM\n");
            }
            break;
        default:
            printf("Unknown state!\n");
            break;
    }
}

// Поток, моделирующий работу кнопок вызова лифта
void* push_button(void* args) {
    char ch;
    while(1) {
        ch = getchar();
        if(ch == 'q')
            break;
        switch(ch) {
            case 'u':
                // Посылается сигнал Up
                kill(getpid(), Up);
                break;
            case 'd':
                // Посылается сигнал Down
                kill(getpid(), Down);
                break;
            default:
                // Игнорирование остальных символов
                break;
        }
    }
    return NULL;
}

int main(int argc, char *argv[]) {
    pthread_t t;
    struct sigaction sa;
    
    printf("Start\n");
    
    // Настройка обработчика сигналов для Up и Down
    sa.sa_sigaction = lift_control;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_SIGINFO;
    
    if(sigaction(Up, &sa, NULL) == -1) {
        perror("sigaction Up");
        exit(EXIT_FAILURE);
    }
    if(sigaction(Down, &sa, NULL) == -1) {
        perror("sigaction Down");
        exit(EXIT_FAILURE);
    }
    
    // Создание потока для обработки ввода кнопок
    if(pthread_create(&t, NULL, push_button, NULL) != 0) {
        perror("pthread_create");
        exit(EXIT_FAILURE);
    }
    
    // Ожидание завершения потока push_button
    pthread_join(t, NULL);
    
    printf("Finish\n");
    return EXIT_SUCCESS;
}

/*
Лог программы:
Start
u
Received signal: 48 in state: 2
This Floor, door is opened
*** Go UP
*** Go UP
*** Go UP
Elevator reached TOP
u
Received signal: 48 in state: 0
*** Go DOWN
*** Go DOWN
*** Go DOWN
This Floor, door is opened
*** Go UP
*** Go UP
*** Go UP
Elevator returned to TOP
d
Received signal: 49 in state: 0
*** Go DOWN
*** Go DOWN
*** Go DOWN
This Floor, door is opened
*** Go DOWN
*** Go DOWN
*** Go DOWN
Elevator reached BOTTOM
d
Received signal: 49 in state: 1
*** Go UP
*** Go UP
*** Go UP
This Floor, door is opened
*** Go DOWN
*** Go DOWN
*** Go DOWN
Elevator returned to BOTTOM
q
Finish
 */

Соседние файлы в папке 4