Добавил:
jetu
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:T2
.c/*
* Выполнил: —, 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
*/