Как передавать события сигналами реального времени в Bash
Не одевай 3.14зду в лапти, она и так смешная.
читать первым в телеграм читать первым в макс
Так-с, давай покончим с сигналами реального времени (СРВ) и выйдем на новый уровень написания Bash-скриптов, мы ж с тобой уже взрослые.
Вчера мы выяснили: СРВ имеют условный индекс 34–64 (в разных дистрибутивах может быть по-разному, проверяй).
Где их применять?
Давай глянем на примере. Сишкой задрачивать не буду, перепишем на Bash.
Задача: у меня есть серверный процесс, который должен получить уведомление от клиента с некоторыми данными (например, номер задачи).
Вместо передачи данных через файлы или другие средства нужно использовать сигналы реального времени.
Пишем сервер signal_listener.sh
#!/bin/bash
handle_signal() {
echo "Получен сигнал $1"
echo "Переданные данные: $2"
}
trap 'handle_signal SIGRTMIN+0 "Task 1 выполнена"' RTMIN+0
trap 'handle_signal SIGRTMIN+1 "Task 2 выполнена"' RTMIN+1
echo "Слушатель запущен. PID: $$"
echo "Ожидаем сигналы..."
while true; do
sleep 1
done
Пишем клиент signal_sender.sh
#!/bin/bash
if [ $# -ne 2 ]; then
echo "Использование: $0 <PID> <TASK>"
echo "TASK может быть 1 или 2"
exit 1
fi
PID=$1
TASK=$2
if [ "$TASK" -eq 1 ]; then
kill -RTMIN+0 $PID
echo "Отправлен сигнал SIGRTMIN+0 (Task 1) процессу с PID $PID"
elif [ "$TASK" -eq 2 ]; then
kill -RTMIN+1 $PID
echo "Отправлен сигнал SIGRTMIN+1 (Task 2) процессу с PID $PID"
else
echo "Ошибка: TASK должен быть 1 или 2"
exit 1
fi
trap = перехватываем сигналы, для СРВ пишем: RTMIN+0 и RTMIN+1.
kill -RTMIN+N = отправляет СРВ. Номер сигнала (например, RTMIN+0) задаёт, какой именно сигнал будет обработан.
chmod +x signal_listener.sh signal_sender.sh
Запускаем первый скрипт, видим его PID:
Слушатель запущен. PID: 20821
Во втором терминале запускаем второй скрипт:
./signal_sender.sh 20821 1
Отправлен сигнал SIGRTMIN+0 (Task 1) процессу с PID 20821
Не забываем подставить PID, который выдал первый скрипт.
После отправки СРВ в терминале, где запускали первый скрипт, видим:
Получен сигнал SIGRTMIN+0
Переданные данные: Task 1 выполнена
Вот это нихуя себе! То есть signal_sender подключился к процессу 20821 и передал в него данные.
В нашем случае данные — это 1 или 2. А скрипт signal_listener успешно это схавал и переварил, исходя из логики.
Использование СРВ открывает ОГРОМНЫЕ возможности, чтобы несколько скриптов или приложений взаимодействовали друг с другом на низких уровнях, не используя велосипеды и прокладки.
А когда какой сигнал использовать?
Хе… 34–64… Если у тебя несложная логика, можешь использовать любой индекс в этом диапазоне. Но если логика совсем ебанутая, то логичнее использовать СРВ с разными индексами для передачи данных.
Например, тебе нужно обрабатывать разные типы событий. В этом случае проще разделить их на разные сигналы.
Типа такого:
SIGRTMIN+0 (34): "Начать обработку данных"
SIGRTMIN+1 (35): "Обновить конфигурацию"
SIGRTMIN+2 (36): "Выебать медведя в жопу"
SIGRTMIN+3 (37): "Остановить обработку данных"
Это избавляет от необходимости декодировать данные внутри обработчика, потому что обработка сразу зависит от типа сигнала.
А можно обрабатывать в порядке приоритета. СРВ обрабатываются в порядке их номеров (от SIGRTMIN к SIGRTMAX). Это заебись, если у тебя задачи с разным приоритетом.
SIGRTMIN+0: Высший приоритет (аварийная задача)
SIGRTMIN+1: Средний приоритет (регулярные уведомления)
SIGRTMIN+2: Низший приоритет (обновление статистики)
Если сигналы поступают одновременно, сначала обработается SIGRTMIN+0, потом SIGRTMIN+1 и т. д.
Если что-то ещё вспомню, накидаю отдельным постом.
Удачи тебе и береги себя!
Про сигналы писал ранее тут, тут, тут и тут.
