Приветствую, коллеги. Надеюсь, что предлагаемая мною статья придется вам по вкусу, а открываемый ею цикл найдет свою аудиторию. Будут ли другие публикации по теме, решать отчасти и вам, поэтому прошу активно высказываться в комментариях по поводу актуальности и качества материала.
Некоторое время назад я сменил специализацию. Это был не просто переход к другому языку программирования или сосредоточение на иной области задач, но и весьма ощутимое изменение парадигмы, которой я придерживался. Год назад я окунулся в мир dataflow и визуального программирования. Наиболее ярким и мощным представителем этой ветви средств разработки является LabVIEW (National Instruments). К сожалению, информации на Хабре по этой теме практически нет, поэтому я и попытаюсь заполнить пробел.
Я не претендую на полноту изложения материала, не собираюсь писать учебное пособие — их достаточно. Главная задача, которую я ставлю перед собой — это освещение концепции LabVIEW и некоторых технологий создания ПО в этой среде. Возможно, кому-то это поможет сделать оптимальный выбор средства разработки, кого-то — подтолкнет к решению задач в своей области новым методом. Наконец, полезно просто расширить кругозор.
Теперь, хотелось бы сделать небольшую паузу и предложить вам познакомиться с единственным постом о LabVIEW, который все-таки обнаружился на Хабре. Мой коллега, увы, так больше и не проявил себя по этой теме, поэтому эстафету принимаю я. Надеюсь, после прочтения его публикации вы вернетесь к моей, и мы продолжим…
* * *
В этой публикации мне хотелось бы вкратце рассказать о том, как реализовать на LabVIEW простейший автомат. Не буду вдаваться в объяснения о том, что такое автоматное программирование, изображения скажут больше. Грамотно продуманная диаграмма состояний автомата позволит сделать код удобным для разработчика, а программу — стабильной. Но в начале, небольшое отступление. Я проясню некоторые моменты LabVIEW.
Итак, слева от цикла мы видим скалярную переменную со значением, раным нулю. Пятерка присоединенная к N говорит циклу о пяти итерациях, т.е. i = 0..4.
Заводим переменную в цикл двумя разными способами — либо через туннель, либо через сдвиговый регистр. Чуть позже увидим разницу между этими вариантами. Верхние три "провода" просто насквозь проходят цикл, однако на выходе — разное. Первый верхний выход имеет автоиндексацию, следовательно на выходе будет не ноль, а массив из пяти нулей. Второй выход выдаст нам тот же ноль, что и на входе. Третий выход, свдиговый регистр, так же даст нам ноль. Вроде бы, никаких отличий от простого туннеля, однако — читайте дальше.
Посмотрим теперь на "проводки", которые в цикле заводятся на узел сложения. Складывать будем с переменной i, т.е. с номером итерации.
Что же будет на выходе? Поскольку мы складываем с нулем (та переменная, что заведена снаружи цикла), мы увидим на четвертом выходе (с автоиндексацией) массив [0,1,2,3,4]. Логично. Что же будет в пятом? Последнее значение i. Туннель не имеет автоиндексации и перезаписывается.
А что в последнем выходе? А вот там будет 10. (0 + 1 + 2 +3 +4) Почему? Потому что сдвиговый регистр на входе будет передавать в следующую итерацию цикла предыдущее значение выхода, и, лишь на первой итерации — внешний нолик, который мы подали на вход.
Проверим.
Теперь попробуем сразу перейти к задаче. Предположим, что нам надо написать программу, которая ждет входящее TCP/IP соединение, отправляет данные клиенту, отключает его и возвращается в исходный режим.
Диаграмма приложения, реализующего этот сервис будет такой:
Теперь, взглянем на исходный код.
Главный цикл программы выглядит так:
Кейсы основной структуры и определяют состояния автомата: init, listen, say, quit.
А вот маленькие вложенные кейсы (обработка ошибки соединения и обработка нажатия кнопки выхода) подробнее:
Остальные кейсы основной структуры:
Запускаем программу, соединяемся telnet localhost 10000 и видим в консоли «hello, world!». Затем соединение рвется.
Одна из главных особенностей визуального программирования — код действительно может быть наглядным и красивым! С другой стороны, он может запросто превратиться в лапшу, все-таки мы имеем дело с «проводками» dataflow. Однако в LabVIEW есть ряд средств (очереди, локальные, глобальные, сетевые переменные, свойства элементов управления и прочее), который позволяет улучшить читаемость кода. Правда, в ущерб идеологии dataflow. Да что там говорить, есть даже специальные структуры для контроля за событиями пользовательского интерфейса. Есть ООП! А в LabVIEW 2009 есть даже рекурсия, которая ну никак не вписывается в dataflow. Однако, несмотря ни на что, LabVIEW более чем достоин того, чтобы иметь его ввиду при выборе инструмента разработки.
P.S. Начиная с версии 8.6 в LabVIEW появились специальные инструменты для автоматного программирования. Пока что мне не довелось использовать их в работе, однако, на первый взгляд, они делают модель автомата еще более наглядной. Представится возможность — расскажу.
Спасибо за внимание.
01.10.2009
Китьян Павел
Dataflow + G = LabVIEW
Некоторое время назад я сменил специализацию. Это был не просто переход к другому языку программирования или сосредоточение на иной области задач, но и весьма ощутимое изменение парадигмы, которой я придерживался. Год назад я окунулся в мир dataflow и визуального программирования. Наиболее ярким и мощным представителем этой ветви средств разработки является LabVIEW (National Instruments). К сожалению, информации на Хабре по этой теме практически нет, поэтому я и попытаюсь заполнить пробел.
Я не претендую на полноту изложения материала, не собираюсь писать учебное пособие — их достаточно. Главная задача, которую я ставлю перед собой — это освещение концепции LabVIEW и некоторых технологий создания ПО в этой среде. Возможно, кому-то это поможет сделать оптимальный выбор средства разработки, кого-то — подтолкнет к решению задач в своей области новым методом. Наконец, полезно просто расширить кругозор.
Теперь, хотелось бы сделать небольшую паузу и предложить вам познакомиться с единственным постом о LabVIEW, который все-таки обнаружился на Хабре. Мой коллега, увы, так больше и не проявил себя по этой теме, поэтому эстафету принимаю я. Надеюсь, после прочтения его публикации вы вернетесь к моей, и мы продолжим…
* * *
В этой публикации мне хотелось бы вкратце рассказать о том, как реализовать на LabVIEW простейший автомат. Не буду вдаваться в объяснения о том, что такое автоматное программирование, изображения скажут больше. Грамотно продуманная диаграмма состояний автомата позволит сделать код удобным для разработчика, а программу — стабильной. Но в начале, небольшое отступление. Я проясню некоторые моменты LabVIEW.
Туннели и шифт-регистры.
Итак, слева от цикла мы видим скалярную переменную со значением, раным нулю. Пятерка присоединенная к N говорит циклу о пяти итерациях, т.е. i = 0..4.
Заводим переменную в цикл двумя разными способами — либо через туннель, либо через сдвиговый регистр. Чуть позже увидим разницу между этими вариантами. Верхние три "провода" просто насквозь проходят цикл, однако на выходе — разное. Первый верхний выход имеет автоиндексацию, следовательно на выходе будет не ноль, а массив из пяти нулей. Второй выход выдаст нам тот же ноль, что и на входе. Третий выход, свдиговый регистр, так же даст нам ноль. Вроде бы, никаких отличий от простого туннеля, однако — читайте дальше.
Посмотрим теперь на "проводки", которые в цикле заводятся на узел сложения. Складывать будем с переменной i, т.е. с номером итерации.
Что же будет на выходе? Поскольку мы складываем с нулем (та переменная, что заведена снаружи цикла), мы увидим на четвертом выходе (с автоиндексацией) массив [0,1,2,3,4]. Логично. Что же будет в пятом? Последнее значение i. Туннель не имеет автоиндексации и перезаписывается.
А что в последнем выходе? А вот там будет 10. (0 + 1 + 2 +3 +4) Почему? Потому что сдвиговый регистр на входе будет передавать в следующую итерацию цикла предыдущее значение выхода, и, лишь на первой итерации — внешний нолик, который мы подали на вход.
Проверим.
Задача
Теперь попробуем сразу перейти к задаче. Предположим, что нам надо написать программу, которая ждет входящее TCP/IP соединение, отправляет данные клиенту, отключает его и возвращается в исходный режим.
Диаграмма приложения, реализующего этот сервис будет такой:
Теперь, взглянем на исходный код.
Главный цикл программы выглядит так:
Кейсы основной структуры и определяют состояния автомата: init, listen, say, quit.
А вот маленькие вложенные кейсы (обработка ошибки соединения и обработка нажатия кнопки выхода) подробнее:
Остальные кейсы основной структуры:
Запускаем программу, соединяемся telnet localhost 10000 и видим в консоли «hello, world!». Затем соединение рвется.
Сухой остаток
Одна из главных особенностей визуального программирования — код действительно может быть наглядным и красивым! С другой стороны, он может запросто превратиться в лапшу, все-таки мы имеем дело с «проводками» dataflow. Однако в LabVIEW есть ряд средств (очереди, локальные, глобальные, сетевые переменные, свойства элементов управления и прочее), который позволяет улучшить читаемость кода. Правда, в ущерб идеологии dataflow. Да что там говорить, есть даже специальные структуры для контроля за событиями пользовательского интерфейса. Есть ООП! А в LabVIEW 2009 есть даже рекурсия, которая ну никак не вписывается в dataflow. Однако, несмотря ни на что, LabVIEW более чем достоин того, чтобы иметь его ввиду при выборе инструмента разработки.
P.S. Начиная с версии 8.6 в LabVIEW появились специальные инструменты для автоматного программирования. Пока что мне не довелось использовать их в работе, однако, на первый взгляд, они делают модель автомата еще более наглядной. Представится возможность — расскажу.
Спасибо за внимание.
01.10.2009
Китьян Павел