.
Тогда посоветовали посмотреть в сторону использования СУБД или перенятия методов синхронизации из мира СУБД. Конкретно предложили задать вопрос на форуме БД, что я и сделал
. Литературу мне подсказали, изучаю. Но видимо, поскольку вопрос больше архитектурный, то конкретных ответов не дали. (это типа я прошу не считать данное сообщение за кросспостинг )
Есть конкретная задача, которая как паттерн присуща системам моделирования: её можно назвать "многопоточный MVC".
конкретизирую под системы моделирования, того вида, которым занимаюсь:
Есть объекты(акторы) имеют входные\выходные порты, реализуют определенный мат.оператор над множеством этих портов (сложение, интегрирование, преобразование Фурье(FFT) и т.д.). Модель в целом состоит из таких объектов, связанных в граф. Вершины графа — акторы, дуги соединяют порты акторов.
//актор инкремент увеличивает значение, пришедшее во входящий порт, на значение параметра и пересылает увеличенное значение дальшеclass Incrementer: IActor
{
public double param{get;set;}
public void Fire(){output_port.SendData(input_port.GetData()+param)};
}
Есть своеобразный планировщик (реализующий кооперативную многозадачность среди акторов):
//выдает такт времени каждому актору, обходя графclass Sheduler
{
//в собственном потоке планировщикаvoid HisOwnThread()
{
while(!program_end)
{
foreach(IActor actor in graph)
actor.Fire();
}
}
}
Есть GUI-поток, в котором пользователь создает объекты, строит граф из этих объектов, запускает планировщик и далее при запущенном(sic!) планировщике может изменять граф или менять параметры объектов. В совсем хорошей системе планировщиков может быть много — например, мы хотим какой-либо объект поместить в собственный поток, чтоб он там слушал сетевой порт. Тогда мы для этого объекта создадим собственный планировщик (у этого планировщика будет свой поток). Значит, у нас будет 2 планировщика, значит, нужна будет иерархия планировщик (есть, конечно, и другие варианты).
Теперь вопрос: как впихнуть это в БД? Или даже так использовать ли БД? Основная цель использования БД — упростить синхронизацию потоков. И есть ли БД, которые подходят для такой задачи? (подождите отвечать, ниже приведен текущий вариант решения )
Если использовать БД, то я вижу один способ — поместить данные о графе и параметрах в БД. Тогда программа претерпит такие изменения:
class Incrementer: IActor
{
public double param{get {query("select Incrementer.param from DB");}}
public void Fire(){output_port.SendData(input_port.GetData()+param)};//тут идет обращение к БД, чтоб знать по какой дуге послать данные
}
class Sheduler
{
//в собственном потоке планировщикаvoid HisOwnThread()
{
while(!program_end)
{
graph=BuildNewGraphVersion_form_DataBase();foreach(IActor actor in graph)
actor.Fire();
}
}
}
Думаю тут можно будет прикрутить кэширование, оповещение об изменениях и т.д. Возможно pLINQ(parallelLinq) будет решением этой проблемы, но пока решения не видно и подходящей БД тоже.
Если не использовать БД, то мое текущее решение описано здесь
Велосипедность решения — по сути дела создано собственное объектное хранилище данных и собственный язык запросов
Не гибкость и не типизируемость языка запросов (да, знаю, можно создать DSL, но это ещё один велосипед).
Постоянное раздутие интерпретатора запросов, из-за не универсальности хранилища данных. Так, например, сейчас все параметры и все порты акторов имеют тип double, теперь хочу добавить актор FFT, он на выходе должен выдавать complex — проблема — нужно переделывать всю систему. Или, например, хочу параметру добавить поля: отображаемое имя, видим\невидим в GUI, редактируемый из GUI или нет и прочее, опять же нужно переписывать базовые классы системы. в PtolemyII(см.ниже) это решено за счет тотального полиморфизма (через наследование реализаций), в принципе, конечно, можно и поэтому пути пойти.
Почему изначально не стал использовать БД:
нету опыта, системы моделирования, с которыми я знаком, не используют БД:
Сейчас я ориентировался на архитектуру таких систем как PtolemyII(Беркли) и МВТУ(МГТУ им. Баумана). В этих системах БД не используется, также БД не используется в single-player играх (не сетевых тобишь), а такой вид игр очень напоминает системы моделирования. Причины этого, если честно, мне не очень понятны.
Очень надеюсь на советы или "руководящие вопросы", букв много, ну дак форум такой
Спасибо.
p.s.
ответ на вопрос "зачем мне вообще нужны потоки в такой системе" здесь
Здравствуйте, Didro, Вы писали:
D>Есть конкретная задача, которая как паттерн присуща системам моделирования: её можно назвать "многопоточный MVC". <...> D>Есть объекты(акторы) <...> D>Есть своеобразный планировщик <...> D>Есть GUI-поток, в котором пользователь создает объекты <...>
Вы перечислили различные компоненты системы, которые могут присутствовать, а могут и не присутствовать (зависит, от реализации), но, к сожалению, так и не написали, для чего система нужна. Ни слова не сказано о том, какие задачи она должна решать, в каких условиях она будет использоваться и, вообще, для чего нужно это моделирование. Попытка разработать архитектуру без ответа на эти ключевые вопросы, на мой взгляд, будет неуспешной.
Здравствуйте, Кирилл Лебедев, Вы писали:
КЛ>Вы перечислили различные компоненты системы, которые могут присутствовать, а могут и не присутствовать (зависит, от реализации), но, к сожалению, так и не написали, для чего система нужна. Ни слова не сказано о том, какие задачи она должна решать, в каких условиях она будет использоваться и, вообще, для чего нужно это моделирование. Попытка разработать архитектуру без ответа на эти ключевые вопросы, на мой взгляд, будет неуспешной.
Полностью согласен
Осознал эту промашку уже после написания поста (постепенно начинаешь воспринимать цель разработки системы как не что само сабой разумеющееся). Попробую повторно задать ворпос немного позже, сформулировав его более корректно и менее зависимо от контекста.
Возможно я не до конца вник в проблему, поэтому возможно скажу глупость, а может наоборот свежий взгляд с другой колокольни.
Как я понимаю, модель должна состоять из двух частей. Первая — статическая, это то, что задаёт пользователь, и никак кроме как пользователем она не меняется. Вторая — динамическая, это набор динамических транзиентных величин, которые связаны с элементами статической модели.
Я правильно понял?
Если так, то я вижу следующее решение. Каждый элемент модели явно разбить на 2 составляющих — статическую и динамическую. Каждый элемент хранит соотв. статические или динамические параметры.
При этом динамический элемент находится на более высоком уровне, чем статический. Т.е. он содержит ссылку на последнего.
При изменении модели надо просто атомарно подменить у всех (или части) динамических элементов ссылки на новые статические элементы. Тогда, когда динамический элемент в следующий раз обратится за параметрами статической модели, он будет работать уже с новыми параметрами.
Если элемент модели удалился пользователем совсем, то можно заменить ссылку на NULL. Тогда динамический элемент поймёт, что его удалили.
При добавлении элемента модели, надо создать новый элемент статической и динамической модели.
Набросок кода:
/** Элемент статической модели
*/struct static_model_node
{
/** Набор параметров элемента */
std::vector<int> params;
/** Набор связей с другими элементами */
std::vector<static_model_node*> links;
};
struct dynamic_model_node
{
/** Ссыла на элемент со статическими параметрами */
static_model_node* sm_node;
/** Набор динамических параметров элемента */
std::vector<int> params;
void do_something()
{
std::vector<int> const& params = sm_node->params;
std::vector<static_model_node*> const& links = sm_node->links;
//...
}
};
Проблема с атомарной транзакционной подменой всех элементов статической модели. Но, я думаю, она решается.
Решение с БД видится слишком тяжеловесным и общим (в плохом смысле этого слова).
Здравствуйте, Didro, Вы писали:
D>Если использовать БД, то я вижу один способ — поместить данные о графе и параметрах в БД. Тогда программа претерпит такие изменения: D>
D>class Incrementer: IActor
D>{
D> public double param{get {query("select Incrementer.param from DB");}}
D> public void Fire(){output_port.SendData(input_port.GetData()+param)};//тут идет обращение к БД, чтоб знать по какой дуге послать данные
D>}
D>
Т.е. ты хочешь использовать SERIALIZED уровень видимости транзакций в БД, что бы модификации модели происходили атомарно?
Здравствуйте, remark, Вы писали:
R>Т.е. ты хочешь использовать SERIALIZED уровень видимости транзакций в БД, что бы модификации модели происходили атомарно?
Если так, то это можно легко реализовать и без БД.
struct static_model_node
{
//...
};
typedef int node_id;
struct static_model
{
hash_map<node_id, static_model_node> map;
};
atomic_register<static_model> model;
struct dynamic_model_node
{
node_id id;
void make()
{
static_model& m = model.load();
if (!m.map.find(id))
return; // меня удалили из модели
static_model_node& n = m.map.find(id);
// работаем с параметрами из n
}
};
Решение с БД здесь всё-таки видится как overkill, который даст больше проблем, чем решит. Потом придётся затыкать те проблемы (прикручивание кэша), а потом новые и т.д.
R>
КЛ>Вы перечислили различные компоненты системы, которые могут присутствовать, а могут и не присутствовать (зависит, от реализации), но, к сожалению, так и не написали, для чего система нужна. Ни слова не сказано о том, какие задачи она должна решать, в каких условиях она будет использоваться и, вообще, для чего нужно это моделирование. Попытка разработать архитектуру без ответа на эти ключевые вопросы, на мой взгляд, будет неуспешной.
Так автор же назвал, на что система должна быть похожа. На Ptolemy II, МВТУ. Simulink из той же, ИМХО, оперы.
По долгу службы мне в последнее время приходится заниматься задачами process control, диагностикой реакторных установок, DSP и т.п.
И я, точно так же как и Вы, пришёл к необходимости создания ПО в виде графа акторов с входами-выходами. Данный подход называется Flow Based Programming. В моём случае, наиболее подходящей системой из существующих я бы назвал LabVIEW. Но ряд серьёзных недочетов в этой системе убивают (для меня) LabVIEW на корню. Недочетов много, перечислять можно довольно долго. Из самых основных назову проприетарность и наличие императивных конструкций (for, switch и т.д.), делающих мало-мальски серьёзные блок-схемы LabVIEW совершенно нечитабельными и непечатными. Слышал, как LabVIEW называли "графическим матерным" языком.
Итак, вот мои предварительные соображения:
разработать графическую нотацию и редактор блок-схем, её использующий;
разработать открытый формат хранения блок-схем;
разработать среду исполнения блок-схем;
использовать по-максимуму POSIX для обеспечения переносимости;
сделать каждый актор самодостаточным, единожды тестируемым, не требующим перекомпиляции, бинарным модулем;
свести к минимуму зависимости акторов друг от друга;
обеспечить механизмы пропагации и отработки нештатных ситуаций и корректное самовосстановление системы в процессе работы;
возложить ответственость за выделение/освобождение памяти на акторов, этой памятью владеющих;
все пакеты данных между акторами передавать в одной нити. Естественно, I/O-bound акторы могут создавать свои нити для внутреннего использования. Но другие акторы и среда исполнения, в общем случае, ничего не должны знать об этих нитях. (Данное решение вообще-то потенциально убьёт масштабируемость, и по-любому потребует пересмотра);
сделать акторов самодокументируемыми сущностями, содержащими справку о себе и паттерны своего использования;
использовать чистый С в качестве основного (но не единственного) языка разработки акторов (тут наши с Вами пути, очевидно, разойдутся);
(естественно, к редактору блок-схем это не относится. GUI на C — самоубийство. )
Акторы будут подразделяться на:
источники сигналов;
обработчики сигналов (фильтры, корреляторы, БПФ и т.д.);
актуаторы;
рекордеры;
секвенсоры (по таймеру выдают последовательности управляющих сигналов). По-хорошему требуют наличия RTOS под собой;
блоки HMI (human-machine interface). HMI могут быть как экранными UI, так и аппаратными панелями управления/отображения;
аггрегаторы (объединяют граф суб-акторов в одном акторе);
блоки связи (IP, modbus, CAN, bluetooth, ZigBee и т.д.);
вспомогательные сущности (обработчики нештатных ситуаций, мультиплексоры, селекторы, диспетчеры потока управления, FSM, преобразователи формтов данных и т.п.).
Заранее отвечу на несколько вопросов
Q: А кому вообще всё это надо?
A: Мне, хотя бы. Для обеспечения конкурентного преимущества себя-в-будущем над собой-нынешним
Q: Зачем такой изврат?
A: Забодал императив! Хочу конструировать приложения в полноценной САПР.
Q: Почему чистый C? Ты что, самоубийца?
А: В С++ трудно отделить интерфейс от реализации в шаблонном коде. В C++ нет стандартов на ABI. Кроме того, я не вижу никакой сложности в разработке небольших автономных сущностей на С. Это что-то вроде небольших UNIX-утилит, написанных на чистом С, и общающихся через stdin/stdout. Кроме того, никто не запрещает использовать С++ для написания модулей. Вот только интерфейсы из модуля должны торчать С-шные. И никаких падающих наружу исключений. С# вообще от лукавого, в силу непереносимости. А Java мне аппетит портит.
Q: Акторов не напасёшься на все случаи жизни.
А: Не напасусь — создам новые под задачу. И в репозитарий их, в репозитарий. В конце концов, ассортимент электронных компонентов исчисляется многими миллионами. Чем программные компоненты хуже?
Q: Осилишь такой объём в одиночку?
A: Естественно, нет. Прекрасно отдаю себе отчёт в масштабности подобной работы. Планирую после плучения первого работающего прототипа писать кандидатскую по этой теме. А там, глядишь, и народ подтянется. К коммерческой выгоде на данном поприще я пока что не стремлюсь. Мне это просто интересно. А кормиться у меня и фрилансом неплохо получается
PS. Пока всё это писал, Вы написали мне про Ptolemy II. Очень любопытно, посмотрю обязательно. Только я привередливый — если качество редактора и целевого приложения меня не устроят — буду всё же делать сам.
Здравствуйте, iiice, Вы писали:
I>Добрый день, коллега!
Добрый,
раза три начинал писать ответ, поэтому напишу кратко:
Написать то, что вы хотите реально. Если будете писать один (как следует из ваших постов), то это будет глючный (уж извините), не полноценный, не цельный и не поддерживаемый проект. Поэтому цели весьма и весьма туманны, я бы посоветовал взять Птолимей или сходную систему и кастомизировать её под свои задачи, благо Птолимей поставляется с исходными кодами и поддержка пока что у него хорошая. Про цели: я так и не понял, что за продукт вы хотите сделать? Кто его целевая аудитория, разработку каких классов приложений собираетесь "покрыть" создаваемым инструментом ?
Например, почему для создания МВТУ\PtolemyII\Simulink\LabView не применялись МВТУ\PtolemyII\Simulink\LabView ? Не находите это странным?
Да и чисто теоретически, есть несколько типов языков моделирования [1](и систем моделирования соответственно), основным критерием классификации языков моделирования по Киндлеру является критерий "Активность vs Транзакт" — Активность это, грубо, актор по нашему, Транзакт — это статичная часть модели, данное, если хотите. Так вот существуют языки А, ТА, АТ, Т соответственно. Поэтому акторы не являются общеуниверсальным средством моделирования и, следовательно, средством создания систем.
Так, например, в системе документооборота Транзактами будут документы, а Активностей может вообще не быть — Активностиями в этой системе будут люди, исполнители документов. Конечно можно извратить систему и впихнуть её в язык типа А.
Есть отдельный класс языков, называемых, координационными языками. Языки этой группы находятся над языками реализаций. Тоже один из подходов к созданию компонентных систем.
Скажем в ваших пунктах не хватает информации о тех самых Транзактах, о которых я писал выше. Скажем есть актор Отображение на Плоттере, он должен быть полиморфен по отношению к данным — должен уметь отображать и комплексные и вещественные ряды, и гистограммы и годографы. Да и вообще нужно такое понятие как тип данных в такой системе, о котором вы почему-то ничего не написали.
Итог:
Я считаю этот проект крайне не сбалансированным, цели его не понятны (кроме как доказать себе любимому, что можете такой проект создать. Почему бы тогда в Космос не слетать, тоже стимул хороший) и реальную конкуренцию специализированным средствам он не составит.
Поэтому могу только предложить вам выбрать более реалистичные цели, которые были б интересны не только вам.
--
1. Киндлер "Языки моделирования", в электронном виде я её не встречал.
D>Про цели: я так и не понял, что за продукт вы хотите сделать? Кто его целевая аудитория, разработку каких классов приложений собираетесь "покрыть" создаваемым инструментом ?
АСУТП, цифровая обработка сигналов, системы диагностики. Для электронного, так сказать, музицирования данная архитектура также идеальна — мне эта тематика также интересна. В качестве хобби.
О продукте (инструменте) говорить рано — я бы пока назвал это исследовательским проектом.
D>Например, почему для создания МВТУ\PtolemyII\Simulink\LabView не применялись МВТУ\PtolemyII\Simulink\LabView ? Не находите это странным?
Могу сказать о LabVIEW — большая часть сущностей предметной области (акторов, по-нашему) написаны на самом LabVIEW. Естественно, к редактору это не относится. Про среду исполнения ничего не могу сказать, но думаю, что вряд ли.
D>Да и чисто теоретически, есть несколько типов языков моделирования [1](и систем моделирования соответственно), основным критерием классификации языков моделирования по Киндлеру является критерий "Активность vs Транзакт" — Активность это, грубо, актор по нашему, Транзакт — это статичная часть модели, данное, если хотите. Так вот существуют языки А, ТА, АТ, Т соответственно. Поэтому акторы не являются общеуниверсальным средством моделирования и, следовательно, средством создания систем.
Спасибо, обязательно почитаю. Из книг схожей тематики читал пока только Жана Поля Моррисона, давнего апологета Flow Based Programming, и создателя одной из первых реализаций FBP.
D>Так, например, в системе документооборота Транзактами будут документы, а Активностей может вообще не быть — Активностиями в этой системе будут люди, исполнители документов. Конечно можно извратить систему и впихнуть её в язык типа А.
D>Есть отдельный класс языков, называемых, координационными языками. Языки этой группы находятся над языками реализаций. Тоже один из подходов к созданию компонентных систем.
Спасибо за сведения.
D>Скажем в ваших пунктах не хватает информации о тех самых Транзактах, о которых я писал выше. Скажем есть актор Отображение на Плоттере, он должен быть полиморфен по отношению к данным — должен уметь отображать и комплексные и вещественные ряды, и гистограммы и годографы. Да и вообще нужно такое понятие как тип данных в такой системе, о котором вы почему-то ничего не написали.
На первых порах остановлюсь на типизации а-ля COM Variant.
D>Итог: D>Я считаю этот проект крайне не сбалансированным, цели его не понятны (кроме как доказать себе любимому, что можете такой проект создать. Почему бы тогда в Космос не слетать, тоже стимул хороший) и реальную конкуренцию специализированным средствам он не составит.
Цель — в первую очередь повысить продуктивность собственного труда. Во вторую очередь — работать с интересом и воодушевлением. А что способствует этому лучше, чем собственные наполеоновские планы?
D>Поэтому могу только предложить вам выбрать более реалистичные цели, которые были б интересны не только вам.
Спасибо за совет. В итоге я остановился на мысли: ознакомиться с теоретическими работами в данной области, оценить практические наработки (тот же Птолемей), вдумчиво составить для себя список достоинств и недостатков существующего инструментария, а потом уже решать — стоит ли браться за собственный проект. Или же, к примеру, вливаться в Ptolemy community. Понимаете, дело ещё вот в чём: во всех системах dataflow, что я видел, крайне мало внимания уделено юзабельности, эргономичности, и продуманной методологии конструирования логических конструкций. Мало внимания уделено, как мне думается, в силу "немэйнстримности" данных систем. Кому, мол, надо — и так схавает Так что работать ещё есть над чем.
D>1. Киндлер "Языки моделирования", в электронном виде я её не встречал.
А где встречали? В магазинах я тоже такого автора не встречал. И вообще, книг подобной тематики немного. Одна, блин, автоматизация барыжного хозяйства.
---------------------------------
1. J. P. Morrison, "Flow based programming"
Спасибо за ответ, стало гораздо яснее и понятнее. В частности радует область покрытия(АСУТП\DSP) — в начале я думал, что Вы собираетесь создавать универсальный инструмент (именно поэтому и делал выпады в сторону документооборота и в сторону, того что сами инструменты такого класса на них же самих не создаются — что говорит об ограниченности возможностей инструмента или о его специализированности).
Единственное что — что мне все-таки было бы жалко сил и времени на такой инструмент — возможно я просто не чувствую ущербности существующих проектов. Недостатки безусловно есть — например, малая интерактивность (способность изменять параметры во время моделирования). Но такая интерактивность не всегда и нужна. Скажем в том же Ptolemy II интерактивность присутствует, но почти нигде не используется. Точнее говоря, в Ptolemy II автор актора может запретить\разрешить интерактивное взаимодействие с актором из GUI.
D>>1. Киндлер "Языки моделирования", в электронном виде я её не встречал. I>А где встречали? В магазинах я тоже такого автора не встречал. И вообще, книг подобной тематики немного. Одна, блин, автоматизация барыжного хозяйства.
В бумажном виде она есть у моего науч.рука.
Вот в Гугле есть ссылки на издательство, комментарии и прочую инфу.