Введение
Парадигма программирования потоков данных В компьютерном программировании, программирование на основе потоков (FBP) - это парадигма программирования, которая определяет приложения как сети процессов черного ящика, которые обмениваются данными через предопределенные соединения путем передачи сообщений, где соединения определяются внешне для процессов. Эти процессы черного ящика могут быть бесконечно пересоединены для формирования различных приложений без необходимости их внутреннего изменения. Таким образом, FBP, естественно, ориентирован на компоненты. FBP - это особая форма программирования потоков данных, основанная на ограниченных буферах, информационных пакетах с определенным сроком службы, названных портах и отдельном определении соединений.
In computer programming, flow based programming (FBP) is a programming paradigm that defines applications as networks of black box processes, which exchange data across predefined connections by message passing, where the connections are specified externally to the processes. These black box processes can be reconnected endlessly to form different applications without having to be changed internally. FBP is thus naturally component oriented. FBP is a particular form of dataflow programming based on bounded buffers, information packets with defined lifetimes, named ports, and separate definition of connections.
Введение
Программирование на основе потоков определяет приложения, используя метафору "фабрики данных". Он рассматривает приложение не как единый последовательный процесс, который начинается в определенный момент времени, а затем выполняет одну вещь за другой, пока не будет завершен, а как сеть асинхронных процессов, общающихся посредством потоков структурированных кусков данных, называемых "пакетами информации" (IP). С этой точки зрения основное внимание уделяется данным приложения и преобразованиям, применяемым к ним для получения желаемых результатов. Сеть определяется внешне для процессов, как список соединений, который интерпретируется частью программного обеспечения, обычно называемого "планировщиком". Процессы связываются посредством соединений с фиксированной пропускной способностью. Соединение присоединяется к процессу с помощью порта, имеющего имя, согласованное между кодом процесса и определением сети. Более одного процесса может выполнять один и тот же код. В любой момент времени данный ИС может принадлежать только одному процессу или находиться в транзите между двумя процессами. Порты могут быть простыми или массивными, например, для входного порта компонента Collate, описанного ниже. Именно комбинация портов с асинхронными процессами позволяет поддерживать многие долговременные примитивные функции обработки данных, такие как сортировка, объединение, суммирование и т. Д., В виде программных чёрных ящиков. Поскольку процессы FBP могут продолжать выполняться до тех пор, пока у них есть данные для работы и где-то поместить свой выход, приложения FBP обычно работают в меньшем времени, чем обычные программы, и оптимально используют все процессоры на машине, без специального программирования, необходимого для достижения этого. Определение сети обычно является диаграммой и преобразуется в список соединений на каком-либо языке или обозначении более низкого уровня. FBP часто является визуальным языком программирования на этом уровне. Более сложные определения сетей имеют иерархическую структуру, построенную из подсетей с "клепыми" соединениями. Многие другие языки/режимы выполнения, основанные на потоках, построены вокруг более традиционных языков программирования, наиболее примечательным примером является RaftLib, который использует операторы C++ iostream для указания графика потоков. FBP имеет много общего с языком Linda в том, что он, по терминологии Гельернтера и Карьеро, является "языком координации": он по сути языконезависим. Действительно, при наличии планировщика, написанного на достаточно низком языке, компоненты, написанные на разных языках, могут быть связаны друг с другом в одной сети. Таким образом, FBP подходит для концепции языков, специфичных для определенной области, или "мини-языков". FBP имеет "соединение данных", описанное в статье о соединении как самый свободный тип соединения между компонентами. Концепция свободной связи, в свою очередь, связана с концепцией архитектур, ориентированных на обслуживание, и FBP соответствует ряду критериев такой архитектуры, хотя и на более тонкозернистом уровне, чем большинство примеров этой архитектуры. FBP продвигает высокий уровень, функциональный стиль спецификаций, которые упрощают рассуждения о поведении системы. Примером этого является модель распределенного потока данных для конструктивного определения и анализа семантики распределенных многосторонних протоколов.
История
Программирование на основе потоков было изобретено Дж. Полом Моррисоном в начале 1970-х годов и первоначально было реализовано в программном обеспечении для канадского банка. FBP в начале был сильно под влиянием некоторых IBM-языков моделирования периода, в частности GPSS, но его корни уходят вперёд до основополагающей работы Конвея о том, что он назвал coroutines. FBP претерпел ряд изменений названия за эти годы: первоначальная реализация называлась AMPS (Advanced Modular Processing System). Одно крупное приложение в Канаде было запущено в 1975 году, и, по состоянию на 2013 год, оно непрерывно используется в производстве, ежедневно, почти 40 лет. Поскольку IBM считала идеи FBP "слишком похожими на закон природы", чтобы быть запатентованными, они вместо этого поместили основные концепции FBP в общественное достояние, с помощью технического бюллетеня обнародования, "Data Responsive Modular, Interleaved Task Programming System", в 1971 году. Вторая реализация была сделана в качестве совместного проекта IBM Canada и IBM Japan, под названием "Data Flow Development Manager" (DFDM), и была кратко продана в Японии в конце 80-х под названием "Data Flow Programming Manager". В IBM эти понятия назывались "поток данных", но этот термин считался слишком общим, и в конечном итоге было принято название "программирование на основе потоков". С начала 80-х до 1993 года Дж. Пол Моррисон и архитектор IBM Уэйн Стивенс усовершенствовали и продвигали концепции FBP. Стивенс написал несколько статей, описывающих и поддерживающих концепцию FBP, и включил материал о ней в несколько своих книг. В 1994 году Моррисон опубликовал книгу, описывающую FBP, и предоставил эмпирические доказательства того, что FBP привела к сокращению времени разработки.
Понятия
На следующей диаграмме показаны основные элементы диаграммы FBP (за исключением пакетов информации). Такую диаграмму можно преобразовать непосредственно в список соединений, который затем может быть выполнен соответствующим движком (программным или аппаратным обеспечением). A, B и C - это процессы, выполняющие компоненты кода. O1, O2 и два IN являются портами, соединяющими соединения M и N с соответствующими процессами. Процессы B и C могут выполнять один и тот же код, поэтому каждый процесс должен иметь свой собственный набор рабочих запоминающих устройств, блоков управления и т. д. Независимо от того, имеют ли они общий код, B и C могут свободно использовать одни и те же имена портов, поскольку имена портов имеют значение только в компонентах, ссылающихся на них (и, конечно, на уровне сети). M и N - это то, что часто называют "ограниченными буферами", и имеют фиксированную емкость с точки зрения количества ИП, которые они могут содержать в любой момент времени. Концепция портов позволяет использовать один и тот же компонент в нескольких местах сети. В сочетании с возможностью параметризации, называемой пакетами первоначальной информации (IIP), порты обеспечивают FBP возможностью повторного использования компонентов, что делает FBP архитектурой на основе компонентов. FBP таким образом демонстрирует то, что Рауль де Кампо и Нейт Эдвардс из IBM Research назвали конфигурируемой модульностью. Информационные пакеты или IP распределяются в так называемом "IP-пространстве" (так же, как и тупулы Линды распределяются в "тупульном пространстве"), и имеют четко определенный срок службы, пока они не будут удалены и их пространство не будет восстановлено в FBP. Это должно быть явным действием со стороны процесса владения. IP-адреса, перемещающиеся через данное соединение (на самом деле это их "ручки", которые перемещаются), составляют "поток", который генерируется и потребляется асинхронно. Таким образом, эта концепция имеет сходство с концепцией ленивых консолей, описанной в статье Фридмана и Уайза 1976 года. IP-адреса обычно представляют собой структурированные куски данных, однако некоторые IP-адреса могут не содержать реальных данных, а используются просто в качестве сигналов. Примером этого являются "IP-адреса скобки", которые могут использоваться для группировки IP-адресов данных в последовательные паттерны в потоке, называемом "подпотоками". Подпотоки могут в свою очередь быть вложены в гнезда. IP-адреса также могут быть связаны друг с другом, чтобы сформировать "IP-деревья", которые перемещаются по сети как отдельные объекты. Система соединений и процессов, описанных выше, может быть "разветвлена" в любой размер. В процессе разработки приложения процессы мониторинга могут быть добавлены между парами процессов, процессы могут быть "взорваны" в подсети или симуляции процессов могут быть заменены реальной логикой процесса. Поэтому FBP подходит для быстрого создания прототипов. Это действительно образ сборочной линии обработки данных: ИП, проходящие через сеть процессов, можно рассматривать как виджеты, перемещающиеся от станции к станции на сборочной линии. "Машины" можно легко подключить, отключить для ремонта, заменить и так далее. Как ни странно, этот образ очень похож на образ устройства записи, которое использовалось для обработки данных до появления компьютеров, за исключением того, что колоды карт приходилось переносить вручную с одной машины на другую. Реализации FBP могут быть непредприимчивыми или преимущественными. Ранние реализации имели тенденцию быть непредприимчивыми (мейнфрейм и язык C), тогда как последняя реализация Java (см. ниже) использует класс Java Thread и является преимущественной.
Процессы мультиплексирования
Программирование на основе потоков поддерживает мультиплексирование процессов очень естественным образом. Поскольку компоненты читаются только, любое количество экземпляров данного компонента ("процессов") может работать асинхронно друг с другом. Когда компьютеры обычно имели один процессор, это было полезно, когда происходило много ввода-вывода; теперь, когда машины обычно имеют несколько процессоров, это начинает быть полезным, когда процессы также интенсивны. Диаграмма в этом разделе показывает один процесс "балансировщика нагрузки", распределяющий данные между тремя процессами, обозначенными соответственно S1, S2 и S3, которые являются экземплярами одного компонента, который, в свою очередь, вводит данные в один процесс по принципу "по прибытии - по назначению".
Простая интерактивная сеть
В этой общей схеме запросы (транзакции), поступающие от пользователей, вводятся в диаграмму в верхнем левом углу, а ответы возвращаются в нижнем левом углу. "Задние концы" (с правой стороны) связываются с системами на других участках, например, с использованием CORBA, MQSeries и т. Д. Перекрестные соединения представляют запросы, которые не должны идти на задний конец, или запросы, которые должны проходить через сеть более одного раза, прежде чем вернуться к пользователю. Поскольку различные запросы могут использовать разные бэк-энда и могут требовать разного количества времени для бэк-энда (если используется), чтобы обработать их, необходимо предусмотреть связь возвращенных данных с соответствующими запрашивающими транзакциями, например, хэш-таблицами или кэшами. Вышеуказанная диаграмма является схематической в том смысле, что окончательное приложение может содержать много других процессов: процессы могут быть вставлены между другими процессами для управления кэшами, отображения трафика соединения, пропускной способности мониторинга и т. Д. Также блоки на диаграмме могут представлять собой "подсети" небольших сетей с одним или несколькими открытыми соединениями.
Структурированное программирование Джексона (JSP) и Развитие системы Джексона (JSD)
Эта методология предполагает, что программа должна быть структурирована как единая процедурная иерархия подпрограмм. Его исходной точкой является описание приложения как набора "основных линий", основанных на структурах входных и выходных данных. Одна из этих "основных линий" затем выбирается для управления всей программой, а другие должны быть "перевернуты", чтобы превратить их в подпрограммы (отсюда и название "инверсия Джексона"). Иногда это приводит к так называемому "сбою", требующему разделения программы на несколько программ или коррутинов. При использовании FBP этот процесс инверсии не требуется, так как каждый компонент FBP может рассматриваться как отдельная "основная линия". FBP и JSP разделяют концепцию обращения с программой (или некоторыми компонентами) как с анализатором входного потока. В более поздней работе Джексона, Jackson System Development (JSD), идеи были развиты дальше. В JSD проект сохраняется как проект сети до окончательной стадии реализации. Затем модель преобразуется в набор последовательных процессов, соответствующих количеству доступных процессоров. Джексон обсуждает возможность прямого выполнения сетевой модели, которая существует до этого шага, в разделе 1.3 своей книги (курсив добавлен): Спецификация, полученная в конце шага System Timing, в принципе, способна к прямому исполнению. Необходимая среда будет содержать процессор для каждого процесса, устройство, эквивалентное неограниченному буферу для каждого потока данных, и некоторые входные и выходные устройства, где система подключена к реальному миру. Такую среду, конечно, можно обеспечить подходящим программным обеспечением, работающим на достаточно мощной машине. Иногда такое непосредственное исполнение спецификации возможно и может быть даже разумным выбором.
The specification produced at the end of the System Timing step is, in principle, capable of direct execution. The necessary environment would contain a processor for each process, a device equivalent to an unbounded buffer for each data stream, and some input and output devices where the system is connected to the real world. Such an environment could, of course, be provided by suitable software running on a sufficiently powerful machine. Sometimes, such direct execution of the specification will be possible, and may even be a reasonable choice.
Линда .
Многие из концепций в FBP, кажется, были открыты независимо в разных системах на протяжении многих лет. Линда, упомянутая выше, одна из них. Различие между этими двумя методами иллюстрируется методом балансировки нагрузки "школы пираньи" Линды в FBP, для этого требуется дополнительный компонент "балансировщика нагрузки", который направляет запросы на компонент в списке, в котором наименьшее количество IP-адресов ожидает обработки. Очевидно, ФБП и Линда тесно связаны, и один может быть легко использован для имитации другого.
Объектно-ориентированное программирование
Объект в ООП может быть описан как полуавтономная единица, включающая в себя как информацию, так и поведение. Объекты общаются с помощью "призывов методов", которые по сути являются подпрограммными вызовами, выполняемыми косвенно через класс, к которому принадлежит принимающий объект. Внутренние данные объекта могут быть доступны только с помощью вызовов методов, поэтому это форма скрытия информации или "инкапсулирования". Однако инкапсуляция предшествует OOP Дэвид Парнас написал одну из ключевых статей об этом в начале 70-х годов и является базовой концепцией в вычислительной технике. Инкапсуляция - это сама сущность компонента FBP, который можно рассматривать как черный ящик, выполняющий некоторую конверсию своих входных данных в выходные данные. В FBP частью спецификации компонента являются форматы данных и структуры потоков, которые он может принимать, и те, которые он будет генерировать. Это является формой проектирования по контракту. Кроме того, данные в IP могут быть доступны только непосредственно в процессе, который в настоящее время владеет. Инкапсулирование также может быть реализовано на уровне сети, за счет внешних процессов, защищающих внутренние. В статье К. Эллиса и С. Гиббса проводится различие между активными и пассивными объектами. Пассивные объекты включают информацию и поведение, как указано выше, но они не могут определять время этого поведения. А активные объекты, с другой стороны, могут это сделать. В своей статье Эллис и Гиббс утверждают, что активные объекты имеют гораздо больший потенциал для развития устойчивых систем, чем пассивные объекты. Применение FBP можно рассматривать как комбинацию этих двух типов объектов, где процессы FBP будут соответствовать активным объектам, в то время как IP будут соответствовать пассивным объектам.
Модель актёра
FBP рассматривает актора Карла Хьюитта как асинхронные процессы с 2 портами: один для входных сообщений и один для сигналов управления. Сигнал управления испускается самим актером после каждого раунда исполнения. Цель этого сигнала - избежать параллельного выполнения тела актера и таким образом позволить получить доступ к полям объекта актера без синхронизации.