Межпроцессное взаимодействие в Python
Для работы сложных систем приходится синхронизировать потоки управления между разными процессами и в Python это делается легко и красиво. Вот например задача: пользователь в веб-браузере генерирует какое либо событие, например нажимает кнопку чтобы включить мотор, причём включенный мотор должен автоматически выключиться через заданный интервал времени
Для реализации этой задачи потребуется взаимодействие нескольких процессов. Взаимодействие между процессами позволяет запускать несколько изолированных потоков обработки данных на различных скоростях. Например, цикл считывания данных с датчиков устройств может работать со скоростью несколько десятков раз в секунду, а цикл обработки логики оперирует с тяжёлыми операциями анализа данных, записи данных в базу, формирования данных для интерфейса управления и тд., что означает, более долгое время итерации. То-есть взаимодействие между этими разновесными циклами лучше всего устраивать асинхронным способом. И хотя выход из нормального режима хотя бы одного компонента делает всю систему частично не работоспособной, но это позволяет масштабировать систему и оснащать механизмами контроля работоспособности и целостности, так например зависший процесс работы с устройствами можно автоматически перезапустить или запустить на удалённом компьютере и взаимодействовать через обычный сокет распределяя нагрузки между узлами кластера.
- сигнал из браузера поступает с помощью Angular + Ajax + RESTful в веб-приложение
- веб-приложение построеное с помощью Flask + Flask_Admin обрабатывает PUT запрос (для обработки требуется авторизация во Flask-приложении)
- генерирует событие подписки в Redis-сервере
- скада-система прослушивая в отдельном потоке события Redis-сервера выхватывает сигнал включения мотора
- запускает метод включения мотора:
- создавая при этом блокировку (threading.Lock)
- посылает команду включения мотора
- запуская таймер отключения мотора
- затем освобождает блокировку
- система переходит в режим автономный режим работы
- через заданный в настройках интервал включается таймер который:
- включает внутреннюю блокировку
- посылает команду выключения мотора
- анализирует состояние мат.модели и меняет статус проходящего "мимо" мотора бревна
- снимает блокировку
- параллельно работает система индикации работы моторов
- в отдельном процессе (multiprocessing.Process) в цикле чтения данных с датчиков считывается состояние датчиков включения мотора
- данные через общую память (multiprocessing.Value) попадают в цикл обработки логики
- обработчик логики отправляет сигнал включения веб-приложению, которое отправит его в браузер с помощью веб-сокета (flask_socketio.SocketIO)
- браузер получив сигнал отображает включение и выключение мотора
Процесс запуска и отладки автоматизированной системы сортировки древесины