SObjectizer — это небольшой фреймворк для упрощения разработки многопоточных приложений на C++ за счет организации асинхронного обмена сообщениями между объектами-агентами.
Проект живет на SourceForge, распространяется под трехпунктной BSD-лицензией.
Если говорить кратко, то в версии 5.5.8 появилось следующее:
приоритеты у агентов и три новых диспетчера, которые выполняют обработку событий с учетом приоритетов;
более удобные средства работы с ad-hoc агентами;
несколько новых примеров.
Если интересны подробности, то сюда, либо сюда, либо сюда.
Краткую информацию о том, что такое SObjectizer можно найти здесь и далее по ссылкам.
Может быть кого-то из читателей темы заинтересует: вот здесь дано описание нового примера, который показывает, для чего может потребоваться создавать несколько экземпляров SO Environment внутри одного приложения, и как это может выглядеть.
SObjectizer обновился до версии 5.5.9. Вкратце изменения таковы:
возможность использовать произвольные типы в качестве типов сообщение (наследование от message_t больше не обязательно, но тип должен быть MoveConstructible);
класс wrapped_env_t, позволяющий работать с SObjectizer Environment в более привычном для ООП стиле;
возможность трассировки механизма доставки сообщения (для упрощения отладки SObjectizer-приложений и поиска ошибок, связанных с подписками и отсылкой сообщений не тем получателям);
новые функции request_value и request_future для упрощения синхронного взаимодействия агентов;
несколько новых вариантов функции send, позволяющие использовать send вместо send_to_agent (что удобно при обобщенном программировании);
исправлено несколько ошибок, добавлена пара новых примеров.
Чуть подробнее об изменениях рассказывается в этой презентации или в этом посте. Полный список изменений можно найти в Wiki.
Версию 5.5.9 можно взять либо из секции Files на SF, либо из Svn-репозитория, либо из зеркала на GitHub (на GitHub-е теперь git submodules не используется, так что самую последнюю версию можно просто скачать с GitHub-а в виде архива и в ней сразу будут все необходимые подпроекты).
Re: В качестве пятничного трепа (смена code convention)
В обсуждениях SO-5 часто упоминалось, что у нас не удобный/понятный API. Есть желание сделать его удобнее и понятнее. Например, вот такой шаг был бы шагом в верном направлении?
Вот какая штука готовиться к релизу в версии 5.5.13. Уже полностью работает, но окончательно не зафиксирована. Поэтому еще есть возможность что-то переделать, если вдруг обнаружатся какие-то фатальные недостатки.
SObjectizer обновился до версии 5.5.13. Подробности релиза можно узнать здесь. Сорри, что не выкладываю краткого описания изменений. Надеюсь, что тем, кто проектом интересуется, не составит труда пройти по ссылке и прочесть нормальное описание релиза.
Re: v.5.5.14, overload control через mchain и планы на ближайшее время...
Плюс более-менее обозначились планы на ближайшее будущее:
подготовка презентации об опыте использования SObjectizer-а и извлеченных из этого опыта уроках;
эксперименты по интеграции SObjectizer-а в GUI-приложения посредством использования механизма mchain-ов;
подготовка еще одной, может быть двух, презентаций для серии Deep Dive into SObjectizer-5.5. По крайней мере нужно рассказать подробнее о диспетчерах. Ну и об mchain-ах, если получится;
проработка двух больших фич для следующих версий SO-5: возможность представления агентов в виде иерархических конечных автоматов (с историческими состояниями, с реакциями на вход-выход и т.д.) и возможность использования в диспетчерах преаллоцированных буферов в качестве очередей сообщений (при этом экземпляр сообщения не создается динамически, как сейчас, а конструируется in-place в буфере диспетчера). Имхо, фичи очень важные, особенно для определенных классов задач. Но пока понятные лишь в общих чертах. Так что здесь еще над чем подумать.
Собственно говоря, если у кого-то есть вопросы/замечания/предложения, то сейчас удобный момент для того, чтобы уделить этому какое-то время. Так, если вам что-то не нравится в SO-5 или чего-то сильно не хватает и вы найдете возможность об этом сказать, то ваши пожелания вполне могут быть учтены в ближайших релизах SObjectizer-а.
SObjectizer -- это небольшой фреймворк для упрощения разработки многопоточных приложений на C++11 за счет использования идей из моделей акторов и publish-subscribe. SObjectizer является OpenSource-проектом и распространяется под трехпунктной BSD-лицензией.
Этот релиз добавляет возможность создания агентов в виде иерархических конечных автоматов. В версии 5.5.15 поддерживаются такие вещи, как композитные состояния, shallow- и deep-история, обработчики входа/выхода, лимиты времени, передача события на обработку в другое состояние (что-то вроде defer) и подавление событий.
Малюсенький примерчик для демонстрации новых возможностей: агент, который реализует мигающий LED-индикатор. Этот агент обрабатывает сигнал `turn_on_off` для включения и выключения режима мигания. Когда режим мигания включен, агент зажигает LED-индикатор на 1.5 секунды, затем тушит его на 0.75 секунды, затем опять зажигает и опять тушит и так до тех пор, пока не получит следующий сигнал `turn_on_off`. В виде диаграммы состояний этот конечный автомат может быть представлен следующим образом:
Код этого агента может выглядеть вот так:
class blinking_led final : public so_5::agent_t
{
state_t off{ this },
blinking{ this },
blink_on{ initial_substate_of{ blinking } },
blink_off{ substate_of{ blinking } };
public :
struct turn_on_off : public so_5::signal_t {};
blinking_led( context_t ctx ) : so_5::agent_t{ ctx }
{
this >>= off;
off.just_switch_to< turn_on_off >( blinking );
blinking.just_switch_to< turn_on_off >( off );
blink_on
.on_enter( []{ /* some device-specific code */ } )
.on_exit( []{ /* some device-specific code */ } )
.time_limit( std::chrono::milliseconds{1500}, blink_off );
blink_off
.time_limit( std::chrono::milliseconds{750}, blink_on );
}
};
Обновилась серия презентаций Dive into SObjectizer-5.5, которая выполняет плавное погружение пользователя в возможности и особенности SObjectizer-а. Теперь все части описывают самую последнюю стабильную версию -- 5.5.15.
Серьезно была переработана самая первая часть, написанная почти год назад. Лишнее украшательство выброшено, примеры чуток упрощены. Вроде бы получилось более-менее неплохо -- основные моменты объяснены и показаны на очень простых примерах.
Предположительно, она будет выпущена в марте или в апреле 2016. Сроки выхода зависят от объема и сложности нововведений. А повлиять на этот объем/сложность можно оставив свою хотелку в обсуждении по ссылке или прямо здесь.
Вышла версия 5.5.16, основные изменения в которой связаны с развитием функционала mchain-ов (аналоги Go-ных каналов):
реализованны функции select для чтения и обработки сообщений сразу из нескольких mchain-ов;
теперь mchain-ы используют MPMC-очереди сообщений, что позволяет вызывать receive и select для одного и того же mchain-а на разных нитях в параллель (в предшествующих версиях это могло привести к голоданию некоторых нитей, если receive был вызван, когда mchain был пуст);
добавлены вспомогательные функции create_mchain, auto_close_* и auto_join для упрощения использования mchain-ов.
Плюс еще несколько изменений, полный список которых можно найти в Wiki проекта.
Некоторые из новых возможностей показаны в следующем простом примере. Три нити генерируют случайные числа и отсылают их в исходящий mchain. Основная нить посредством select вычитывает эти числа из трех каналов. Чтение прекращается когда все нити-генераторы закроют свои исходящие mchain-ы.
#include <so_5/all.hpp>
#include <iostream>
#include <random>
using namespace std;
using namespace std::chrono;
using namespace so_5;
void uint_generator(mchain_t ch, unsigned int values, unsigned int pause)
{
// Chain must be closed at exit.auto ch_closer = auto_close_retain_content(ch);
// Random numer generation stuff.
default_random_engine rnd_dev;
uniform_int_distribution<unsigned int> values_rnd{0, 256};
uniform_int_distribution<unsigned int> pauses_rnd{5, pause};
// Generation for random numbers with random pauses between them.for(unsigned int i = 0; i != values; ++i)
{
// New random value will be sent to output chain.
send<unsigned int>(ch, values_rnd(rnd_dev));
this_thread::sleep_for(milliseconds{pauses_rnd(rnd_dev)});
}
}
void demo(environment_t & env)
{
// Thread for random number generators.
thread first, second, third;
// All threads must be joined at exit.auto thr_joiner = auto_join(first, second, third);
// Output chains for generators.auto ch1 = create_mchain(env);
auto ch2 = create_mchain(env);
auto ch3 = create_mchain(env);
// Generator threads can be launched.
first = thread{uint_generator, ch1, 20, 20};
second = thread{uint_generator, ch2, 15, 25};
third = thread{uint_generator, ch3, 10, 30};
// Receive numbers from generators.
select(from_all(),
case_(ch1, [](unsigned int i) { cout << "first: " << i << endl; }),
case_(ch2, [](unsigned int i) { cout << "second: " << i << endl; }),
case_(ch3, [](unsigned int i) { cout << "third: " << i << endl; }));
}
int main()
{
so_5::wrapped_env_t sobj;
demo(sobj.environment());
}
Свеженький релиз. С исправлениями парочки ошибок, найденных за последнее время.
Но главное не в этом. Главное в том, что минимальной необходимой для SO-5.5 версией GCC теперь является 4.8, а не 4.9, как в предыдущих версиях. И совместимость с GCC-4.8 будет поддерживаться в ближайшие три года. До окончания времени жизни Ubuntu 14.04 LTS.