Некоторый фон
Я работаю над созданием языка программирования для цифрового медиапрограммирования, который должен поддерживать concurrency, используя передачу сообщений без обмена и мягкое реальное время (т.е. изо всех сил пытайтесь вычислить аудио/видео без потери отсчетов или кадров и с постоянной пропускной способностью).
Оказывается, что обе эти функции удивительно сложно комбинировать, главным образом из-за одного конкретного ограничения: код в реальном времени не должен динамически выделять память.
Мой язык должен упростить реализацию чего-то вроде этого:
- Один поток вычисляет образцы звука на основе параметров. Это могут быть, например, значения различных элементов управления синтезаторами. Этот поток работает "в режиме реального времени".
- Один поток получает вход от пользователя или с другого компьютера для изменения этих значений. Это может быть поток GUI, например, реагирование на пользователя, поворачивающегося в ручке с помощью мыши.
Я хочу, чтобы новые значения, установленные пользователем, отправлялись через очередь в механизм синтезатора. Теперь проблема была бы не интересной, если бы я только хотел отправить float и другие атомные значения. Фактически, я хочу, чтобы любые данные могли перетекать из одного потока в другой, даже сложный объект или структуру данных, и это должно быть возможным для любой конфигурации потоков и приоритетов. Без динамического распределения памяти в режиме реального времени это становится очень трудным, не налагая на себя каких-либо произвольных ограничений для программиста.
Erlang часто рекламируется как подходящий для систем реального времени. Я понимаю, что Эрланг никогда не запрещает выделение памяти. Если бы я сделал то же самое, это устранило бы множество проблем за счет введения недетерминированных сроков в код, который выполняет эти распределения.
Вопрос
Итак, что делает Эрланг такой хорошей формой? Использует ли он специальные трюки, чтобы обойти проблемы, вызванные распределением памяти, или полностью игнорирует проблему? Требуется ли еще один подход к реальному времени?
Пример, иллюстрирующий вопрос
Предположим, что мы пишем синтезатор в Erlang, который должен производить 64 сэмпла каждые 50 миллисекунд, в противном случае трещины и попсы в звуке. Предположим также, что когда я перемещаю какой-нибудь слайдер вокруг строки, маленький объект (пусть говорят, это список или кортеж, содержащий имя параметра и новое значение), должен быть отправлен из процесса GUI в аудиопроцесс, где создается копия. Это потребовало бы динамического распределения памяти. Как Erlang поможет мне удостовериться, что это распределение не задерживает мои вычисления звука?