пятница, 3 ноября 2017 г.

[prog.c++] timertt-1.2.1

Сегодня мы выкатили небольшое обновление для нашей библиотеки для работы с таймерами -- timertt. Изменений в ней совсем мало, поэтому никаких громких анонсов мы не делаем.

Во-первых, мы добавили макрос TIMERTT_VERSION, которых хранит в себе версию библиотеки. В десятичном формате YXXXZZZ, где Y -- это мажорный номер версии, X и Z -- минорный номер и номер патча с лидирующими нулями. Т.е. версия 1.2.1 кодируется как 1002001, а версия 1.3.14 будет кодироваться как 1003014. Каюсь, такой макрос нужно было ввести еще в 1.2.0, но хорошая мысля, как говорится, приходит опосля...

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

auto t = tt.allocate();
tt.activate(t, std::chrono::seconds(30), []{...});
...
// Timer needs to be rescheduled.
// Deactivate it first.
tt.deactivate(t);
// Reactivate it.
tt.activate(t, std::chrono::seconds(45), []{...});

В случае, если использовался thread-safe механизм (например, такой, как timer_thread), то эта двойная операция обрабатывалась не очень эффективно -- требовалось два раза захватывать mutex.

Теперь же reschedule выполняет это все внутри себя захватив mutex всего один раз:

auto t = tt.allocate();
tt.activate(t, std::chrono::seconds(30), []{...});
...
// Timer needs to be rescheduled.
tt.reschedule(t, std::chrono::seconds(45), []{...});

Что может быть заметно эффективнее в сценариях, где переназначение таймера используется очень активно.

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

Поэтому reschedule следует использовать с большой осторожностью. Например, достаточно безопасно вызывать reschedule при работе с однопоточными timer_manager-ами. Там вы сами определяете, когда вы вызываете process_expired_timers. Соответственно, если вы находитесь вне process_expired_timers, то reschedule вызывать безопасно. А вот внутри process_expired_timers, т.е. внутри таймерного события, reschedule вызывать нельзя.

Так что еще раз: при работе с reschedule нужно проявлять двойную осмотрительность.

Вообще, в timertt с самого начала существует рекомендация: вместо реактивации таймеров лучше создавать таймеры заново. Т.е. сперва вы вызваете deactivate для старого таймера, затем создаете новый таймер и вызываете для него activate. С учетом того, что timertt может поддерживать темп активации в несколько миллионов таймеров в секунду, мы считаем, что это приемлемый подход. Однако, если кому-то приходится сталкиваться с ситуациями, когда прямо внутри deactivate нужно точно знать, что таймер полностью деактивирован (может быть даже он успел сработать прямо внутри deactivate), то дайте знать. Будем думать, как это побороть. Но не бесплатно. Ну, в том смысле, что это не сможет не сказаться на скорости работы timertt. Хотя, если кто-то возьмется проспонсировать такую доработку, мы тоже не откажемся ;)

среда, 1 ноября 2017 г.

[life.cinema] Очередной кинообзор (2017/10)

Прошел очередной месяц и настало время публиковать список просмотренных фильмов. Как обычно, вначале то, что понравилось больше, затем то, что понравилось меньше. Ну и несколько слов о двух фильмах вне списка в качестве бонуса :)

Джунгли (Jungle, 2017). Не являюсь большим любителем приключенческих фильмов, да и давно не попадалось ничего достойного на эту тему. Но вот "Джунгли" посмотрел с удовольствием. Пожалуй, первый фильм, в котором Дэниэл Рэдклифф у меня не ассоциировался с Гарри Потером.

Авантюристы (The Adventurers, 2017). Простенько, незамысловато, но для развлекательного боевичка -- как раз то, что нужно. Отличный фильм, чтобы отключить мозги и расслабиться.

Сделано в Америке (American Made, 2017). Не фанат байопиков. Так что этот фильм, хоть и сделан качественно, но не зацепил. Единственно, что меня действительно впечатлило, так это то, с какой иронией в американском фильме показаны махинации ЦРУ в Центральной Америке в 1980-е годы. Вот уж, действительно: самое ужасное в советской пропаганде было то, что она говорила правду. Забавно получать подтверждение этому из продукции Голливуда.

Зеленая комната (Green Room, 2015). Более чем скромненько, но, на удивление, атмосферненько и почти что смотрибельно. Мне не хватило логики в поведении злодеев и кровищи в происходящих разборках. Но, если другого выбора нет, то можно глянуть.

Овердрайв (Overdrive, 2017). Фильм явно на аудиторию лет на 30 помладше меня: благородные и остроумные грабители, лихие парни, красивые девушки, крутые тачки, погони по горным серпантинам. При полном отсутствии реалистичности происходящего. Подросткам, наверное, понравится.

Водила (Wheelman, 2017). Как-то уже не первый ловлю себя на одинаковом впечатлении от фильмов Netflix: замах на рубль, а удар... Ну так себе удар. И этот фильм не исключение. Вроде как по ходу дела все было вполне себе смотрибельно и увлекательно, но потом остаешься в недоумении -- а что же это все было? Как-то логические концы у меня не связались и это испортило впечатление о фильме.

Обет молчания (Acts of Vengeance, 2017). Сильно так себе. Не покидало ощущение, что стареющий Антонио Бандерас пытается проделать тот же фокус, который получился у Лиама Нисона: стать брутальной звездой боевиков на шестом десятке. Только у Нисона с первой "Заложницей" это получилось на отлично, а вот у Бандероса с его последними фильмами как-то не очень.

Планета обезьян: Война (War for the Planet of the Apes, 2017). Наконец-то засмотрел. Потерянное время. Снято красиво, конечно же. Но какой же бред! Можно посмотреть только для того, чтобы постоянно стебаться с происходящего на экране.


Отдельно хочу пройтись по двум фильмам, которые не стал включать в общий обзор.

Бегущий по лезвию 2049 (Blade Runner 2049). Как по мне, так это фильм, который не следовало снимать. И не следовало бы смотреть, если первый Blade Runner оставил сильные впечатления. Первый фильм, в свое время, сильно разрывал шаблоны, во-первых, своей визуальной составляющей (которая по тем временам была фантастикой, да и сейчас еще вполне себе смотрится). Во-вторых, сюжетом, который в те времена буквально пленял, т.к. компьютеры и роботы -- это был манящее далекое будущее. В-третьих, отлично показанными характерными героями (особенно мне понравился фрик-ботаник Дж.Ф.Себастиан со своими домашними роботами). Ну и, в-четвертых, конечно же, волшебный саундрек Вангелиса. В новом фильме ничего этого нет. По крайней мере для меня.

Тачки 3 (Cars 3, 2017). Обычно я не включаю в обзоры мультфильмы. Но этот меня приятно поразил. Отличный, добрый мультик. И, как мне показалось, вовсе не детский. В общем, не ожидал, был приятно удивлен.

воскресенье, 29 октября 2017 г.

[prog.c++] Какой код на С++11/14 произвел на вас самое большое впечатление?

В процессе подготовки доклада к GECon-2017 столкнулся с необходимостью привести небольшой, но яркий пример отличия кода на C++11/14 от кода на C++98. Пока в качестве примера я хочу привести код, который наполняет std::vector несколькими значениями, копирует оттуда те элементы, которые удовлетворяют некоторому условию в другой вектор, затем результирующий вектор сортируется и отображается через std::cout. В коде на С++98 это будет сделано через функторы и итераторы. В коде на C++11/14 это уже будет с initializer lists, лямбдами, туплами и range-for.

Однако, есть подозрение, что данный пример окажется слишком объемным и невыразительным. А это не есть хорошо.

К сожалению, с хорошими примерами происходит как с анекдотами: когда очень нужно, то хрен вспомнишь. А когда вспоминаешь, то вокруг уже никого нет.

Посему обращаюсь к читателям: есть ли у вас самые яркие впечатления от знакомства с C++11/14? Вот увидели какой-то код на C++11/14 и поняли, что C++ стал другим и то, что в С++98 требовало кучи приседаний, в C++11/14 записывается легко и непринужденно. Если есть, то не сочтите за труд, поделитесь, пожалуйста.

Upd. Под катом варианты, которые есть на данный момент.