Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Продвинутая машина состояний 
:(
    Опции темы
semibug
Дата 29.6.2010, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



До сих пор пользовался следующей схемой при построении программ:
Крутим главный цикл, а в нем по свичу (группе свичей) от текущего состояния производится вызов тех или иных функциональных блоков.
При увеличении сложности программы наглядность реализуемых в программе алгоритмов как мне кажется начинает теряться.

Есть ли у кого в арсенале более продвинутые способы построения логики приложения кроме цикла со свичами?

PM   Вверх
Earnest
Дата 29.6.2010, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Вообще-то архитектура приложения очень сильно зависит от того, что это за приложение... Автомат - этот как-то чересчур (если не компилятор пишешь). 
Если приложение с пользовательским интерфейсом - так для них давно все придумано - сообщения в том или ином виде. Алгоритмы вообще не должны светиться в архитектуре - это технические детали. А если речь идет именно о реализации какого-то навороченного алгоритма - от него и зависит как строить программу, разные они очень...

Поконкретнее задай вопрос.


--------------------
...
PM   Вверх
semibug
Дата 29.6.2010, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



К примеру имеем пользовательское приложение, с набором кнопочек. Каждая запускает ту или иную задачу, которая может выполнятся длительное (относительно интерфейса) время. Также имеются зависимости задач друг от друга, т.е. какие то можно запустить параллельно, какие то зависят от завершения других.
В качестве вариант 1 можно запускать на событии кнопки поток, и линейно реализовать в нем выполнение конкретной задачи, минусы - синхронизация и другие беды параллельного программирования.
В качестве варианта 2 каждая задача представляется в виде конченого автомата с выполнением одного шага за короткое время, дергаем за этот шажок в цикле и в нем же обрабатываем интерфейс и другие нужды (в т.ч. другие задачи).

PM   Вверх
mes
Дата 29.6.2010, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(semibug @  29.6.2010,  17:03 Найти цитируемый пост)
К примеру имеем пользовательское приложение, с набором кнопочек.


Цитата(semibug @  29.6.2010,  17:03 Найти цитируемый пост)
каждая задача представляется в виде конченого автомата

так чего Вы спрашиваете, как между собой автоматы интегрировать, либо об структуре самого автомата ?
судя по посту - о первом, а по названию темы - о втором..
Если Вам нужно абстракные размышления на общие случаи - то лучше в книжку, ибо в двух словах все не охватишь,  а если что конкретное, тогда сформулируйте задачу почетче smile



--------------------
PM MAIL WWW   Вверх
semibug
Дата 29.6.2010, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



Вопрос в том, как бы поэлегантней построить код, для работы нескольких, возможно одновременных задач. Подход с состоянием и свичами решает задачу, но, как мне кажется, теряется наглядность работы, т.к. действия раскладываются на кусочки, разбросанные, к примеру, по методам класса. Напротив линейное написание выглядит яснее, но для параллельных задач придется запускать потоки и синхронизировать действия.
Возможно это и есть очевидные решения, посему вопрос вызывает удивление. Ну а вдруг? )


PM   Вверх
mes
Дата 29.6.2010, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



В двух словах: между автоматом и средой должен быть удобный интерфейс который скрывает для второго реализацию первого.

Добавлено через 51 секунду
P.S.естественно первый о втором вобще не догадывается smile



--------------------
PM MAIL WWW   Вверх
Abyx
Дата 29.6.2010, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



Использовать boost.statechart или другую библиотеку для КА?
Раз уж нравится использовать КА, почему бы не использовать более мощные средства их реализации, нежели простой switch
PM MAIL   Вверх
semibug
Дата 29.6.2010, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



Abyx, а вот здесь уже интересно, счас почитаю отгуглю..
PM   Вверх
xvr
Дата 30.6.2010, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(semibug @  29.6.2010,  18:27 Найти цитируемый пост)
Вопрос в том, как бы поэлегантней построить код, для работы нескольких, возможно одновременных задач.
Чем multithreading (aka многопоточность) не устраивает? Для набора взаимодействующих задач - модель MVC (Model-View-Controller)

PM MAIL   Вверх
semibug
Дата 30.6.2010, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



xvr, в принципе устраивает многопоточность, хотя и тянет за собой сложности с синхронизацией, и для некоторых проектов не применима (для однозадачных сред). Также возникают проблемы с сохранением/восстановлением состояния задачи (для конечного автомата можно скинуть на диск стейт, потом восстановить). Хотя наглядность кода, выше по моему мнению, особенно для реализации протоколов с каким нибудь железом и их отладки.



PM   Вверх
Earnest
Дата 30.6.2010, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



semibug, так ты же не общую теорию всего изобретаешь. Определись, можно ли использовать на твоем железе многозадачность. И используй, если можно. Это гораздо удобнее, чем закат солнца вручную с помощью переключений. И нет с синхронизацией сложностей - все давно придумано.
А если проекты разные (для разных сред), так и используй разные методы. Ты же розетки не молотком чинишь.


--------------------
...
PM   Вверх
semibug
Дата 4.7.2010, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



Earnest, Согласен.
Возьмем конкретный пример.
Имеем окошко программы с кнопкой "Do It!" и прогресс баром, каркас приложения создан с помощью мастера, выбран MFC.
По нажатию кнопки должна стартовать долгая задача, прогресс которой надо отобразить на прогресс баре. После старта задачи кнопка запуска становится неактивной до завершения задачи.
Варианты связи гуи с задачей:
  1. Выполнение задачи реализовать в виде последовательности кратковременых операций,  по нажатии кнопочки запускать цикл, в котором обновляется гуи и вызывается кусочек от операции, обновить прогресс бар
  2. Выполнение задачи вынести в отдельный поток. По нажатию кнопочки поток начинает выполнение необходимых действий, по таймеру в основном потоке проверяет завершение выполнение задачи, опрашивать (через критическую секцию) состояние прогресса и выводить на форму.
Есть ещё какие-то комбинации наверное.
Собственно какой вариант предпочтительнее(проще, правильней, красивей, более распространенный).



PM   Вверх
xvr
Дата 5.7.2010, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(semibug @  4.7.2010,  23:07 Найти цитируемый пост)
Собственно какой вариант предпочтительнее

3й вариант -
Необходимые действия выносятся в поток, в нем в необходимых местах ставится отправка сообщений в основное окно, в параметрах сообщений закодированы необходимые действия, которое это основное окно и производит (например обновление прогресс индикатора, активация и деактивация кнопок и пр).

Есть еще 4й вариант, уже упоминаемая мною технология MVC, но ее лучше применять там, где уже есть ее поддержка (в Qt например), или где сложность системы перевешивает затраты на реализацию MVC самому
 

PM MAIL   Вверх
mes
Дата 5.7.2010, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(semibug @  4.7.2010,  22:07 Найти цитируемый пост)
Есть ещё какие-то комбинации наверное.

Вынести работу в отдельный _компонент_,  а ГУИ чтоб подавала ему команды, а также брало информацию и отображало себя.



--------------------
PM MAIL WWW   Вверх
Earnest
Дата 5.7.2010, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



xvr, это все равно разновидность второго варианта. Так что semibug прав - вариантов всего 2 - разбить на кусочки или в поток, а как уж с этим потоком перемигиваться - дело десятое.
Я использую оба варианта, причем даже в рамках одного приложения. Выбор зависит от того, насколько сложна выполняемая задача и насколько ей нужна связь с пользователем (или просто с основным потоком) и в каком направлении эта связь. Скажем, если задача должна просто сообщать о своем прогрессе и уметь прерваться (или приостановиться) по требованию пользователя, то поток - самое милое дело. При этом разбиение задачи на кусочки все равно актуально, т.к. надо же и о прогрессе сообщать и проверять, не пора ли закруглиться (я это обычно в одном флаконе реализую, чтобы не размазывать, так удобнее). А если задача должна выбирать тот или иной шаг в зависимости от ответов основного потока, то удобнее запускать ее в главном - в противном случае для обеспечения связи приходится нагромождать такие конструкции, что через некоторое время сам голову ломаешь, как оно работает. Я пробовала оба подхода, причем неоднократно, по спирали. Сейчас думаю так, как выше написано.

Добавлено через 2 минуты и 1 секунду
В описанном тобою случае я бы выбрала поток.


--------------------
...
PM   Вверх
xvr
Дата 5.7.2010, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Earnest @ 5.7.2010,  09:26)
xvr, это все равно разновидность второго варианта. 

Не совсем. У semibug 2й вариант включает не только поток, но и 
Цитата

по таймеру в основном потоке проверяет завершение выполнение задачи, опрашивать (через критическую секцию) состояние прогресса и выводить на форму.
А вот это как раз и не совсем правильно - логику взаимодействия задает основной поток, а реализует эту логику - 2й поток. Более логично было бы отдать и то и другое одному и тому же потоку

Цитата

Так что semibug прав - вариантов всего 2 - разбить на кусочки или в поток, а как уж с этим потоком перемигиваться - дело десятое.
Можно и с отдельным потоком сделать полную ж... (*)  smile 
Так что 2й вариант распадается на несколько меньших подвариантов, и их тоже надо тщательно выбирать  smile 

PM MAIL   Вверх
Earnest
Дата 5.7.2010, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(xvr @  5.7.2010,  12:33 Найти цитируемый пост)
Так что 2й вариант распадается на несколько меньших подвариантов, и их тоже надо тщательно выбирать

Так никто и не спорит. И в первом случае тоже есть разные варианты обеспечения нормальной работы интерфейса.
Цитата(xvr @  5.7.2010,  12:33 Найти цитируемый пост)
А вот это как раз и не совсем правильно - логику взаимодействия задает основной поток, а реализует эту логику - 2й поток. Более логично было бы отдать и то и другое одному и тому же потоку

Не соглашусь, второму (рабочему) потоку должно быть глубоко по барабану, кто и как его прогресс отображает: может, я в двух окнах хочу это сделать (я, кстати, часто так и делаю). И не надо замусоривать (возможно) сложный алгоритм всякой ерундой типа рисования прогресса. UI - дело основного потока. Насчет того, запрашивать прогресс или пусть поток сообщает - не очень существенно, дело вкуса. 
Я понимаю, что тебе не нравится, что основной поток всякой фигней занимается (по таймеру в основном потоке проверяет завершение выполнение задачи), но это решаемо в смысле дизайна. Я, например, написала  специальный управляющий элемент (панель = прогресс + кнопка Стоп), который как совершенно отдельная сущность легко вставляется в любой диалог и требует буквально пары точек взаимодействия (получает хандл задачи и дальше сам с ней разбирается).


--------------------
...
PM   Вверх
xvr
Дата 5.7.2010, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Earnest @ 5.7.2010,  15:41)
Цитата(xvr @  5.7.2010,  12:33 Найти цитируемый пост)
А вот это как раз и не совсем правильно - логику взаимодействия задает основной поток, а реализует эту логику - 2й поток. Более логично было бы отдать и то и другое одному и тому же потоку

Не соглашусь, второму (рабочему) потоку должно быть глубоко по барабану, кто и как его прогресс отображает:

Про отображение речь не шла, речь шла об оповещении, что состояние изменилось.
Цитата

И не надо замусоривать (возможно) сложный алгоритм всякой ерундой типа рисования прогресса. UI - дело основного потока.
UI - да, дело основного потока, а вот извлечение информации для отображения нет. Это должен предоставить рабочий поток. UI может вообще не знать, где и как эта информация представлена
Цитата

Насчет того, запрашивать прогресс или пусть поток сообщает - не очень существенно, дело вкуса. 
Может быть существенно. Данные для отображения генерятся во 2м потоке, и доставлять их проще от источника (и именно в момент генерации) приемнику. Такая система доставки легко и непринужденно ложится на очередь сообщений Windows, и практически ничего за собой не тянет (в смысле объема кода). 
Доставка в противоположном направлении требует синхронизации, защиты разделяемых переменных, и возможно организации callback'ов из основного потока в 2й поток (для запросов) - это явно сложнее, чем один SendMessage
Цитата

Я понимаю, что тебе не нравится, что основной поток всякой фигней занимается (по таймеру в основном потоке проверяет завершение выполнение задачи), но это решаемо в смысле дизайна.
Это совершенно не нужная полумера - или отправлять сообщения 'по течению' (с помощью очереди сообщений Windows), или делать полноразмерную систему MVC. Тут же предлагается подход, удачно сочетающий недостатки обоих систем
Цитата

Я, например, написала  специальный управляющий элемент (панель = прогресс + кнопка Стоп), который как совершенно отдельная сущность легко вставляется в любой диалог и требует буквально пары точек взаимодействия (получает хандл задачи и дальше сам с ней разбирается).
Это уже MVC. Чрезвычайно гибкая и мощная система, но требует кода (как минимум того самого 'специальный управляющий элемент')

PM MAIL   Вверх
Earnest
Дата 5.7.2010, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(xvr @  5.7.2010,  17:27 Найти цитируемый пост)
, и доставлять их проще от источника (и именно в момент генерации) приемнику.

Опять не соглашусь. Иногда - да, так нормально. А иногда лучше основному потоку решать, когда запрашивать. Все зависит от задачи. Скажем, если основному потоку больше делать нечего, как сообщения принимать - ну пусть. 
А представь, что процесс одной перерисовки (я не про прогресс, конечно) весьма ресурсо-емкий. Тогда лучше основной поток сам соображает когда ему лучше обновиться.
Критическая секция - было бы о чем говорить, кроме того, для запроса прогресса можно обойтись Interlock-функциями. В общем, нельзя сказать, что одно решение абсолютно всегда лучше другого.
Цитата(xvr @  5.7.2010,  17:27 Найти цитируемый пост)
Это уже MVC.

Ну да, конечно, только кода там кот наплакал - идея-то простая. 



--------------------
...
PM   Вверх
xvr
Дата 5.7.2010, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(Earnest @ 5.7.2010,  17:28)
Иногда - да, так нормально. А иногда лучше основному потоку решать, когда запрашивать. Все зависит от задачи.

В таком случае основной поток должен знать что то о рабочем потоке, в частности где у него лежит этот самый прогресс и как его достать. А это лишние логические связи в программе
Цитата

А представь, что процесс одной перерисовки (я не про прогресс, конечно) весьма ресурсо-емкий. Тогда лучше основной поток сам соображает когда ему лучше обновиться.
Основной поток может выгрести поступающие сообщения, пока они есть в очереди, и только потом обновится
Цитата

В общем, нельзя сказать, что одно решение абсолютно всегда лучше другого.
Абсолютно - конечно нет. Но если нет явных предпочтений и UI синхронизируемое обновление не является ПОЛНОСТЬЮ тривиальным, то лучше все же отправлять сообщения от рабочего потока. Ну или полный MVC
Цитата

Цитата(xvr @  5.7.2010,  17:27 Найти цитируемый пост)
Это уже MVC.

Ну да, конечно, только кода там кот наплакал - идея-то простая.
Кода не очень много, но он есть. И если нужно засинхронизировать отрисовку ТОЛЬКО прогресс бара и кнопок, то любой дополнительный код вполне может быть излишним smile

PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0638 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.