пятница, 19 мая 2017 г.

[business] Где можно посмотреть примеры текстов коммерческих лицензий на ПО?

Обращаюсь за помощью к своим читателям. Мы думаем некоторые свои разработки распространять под двойной лицензией, т.е. GNU GPL или GNU Affero GPL для использования в OpenSource-проектах + коммерческая лицензия для использования в закрытых проектах. Как раз сейчас работаем над текстом этой самой коммерческой лицензии.

У нас есть несколько текстов коммерческих лицензий от производителей ПО, которые сами продают свое ПО под двойной лицензией. Но это слишком маленькая выборка. Хотелось бы больше.

Посему просьба к читателям блога, у которых случайно завалялся текст какой-нибудь коммерческой лицензии к какому-нибудь OpenSource-софту: могли бы вы поделиться текстом (вычеркнув оттуда всю конфиденциальную информацию, естественно)? Или ссылочкой на подобные тексты в Интернете?

Может быть кто-то может подсказать координаты юристов или юридических компаний в РБ, у которых есть опыт подготовки такого рода лицензий? Именно в РБ.

Связаться со мной можно по мылу eao197 на stiffstream тчк com или eao197 на gmail com.

четверг, 18 мая 2017 г.

[prog] Почему-то сильно не хочется делать CMake основным build-tool-ом

Под влиянием вот этого доклада с C++ CoreHard Spring 2017 решил попробовать еще раз посмотреть в сторону CMake как основного своего build-tool-а. Сам CMake, как по мне, говном был, говном и остался. Но, поскольку люди всерьез интересуются такими построенными поверх CMake вещами, как Conan.io и Hunter, то может пришло время зажать нос и научиться обмазываться CMake-ом?

В чем у меня специфика? В том, что под Windows у меня сейчас, например, десять(!) вполне себе актуальных версий GCC под x64: 4.8, 4.9, 5.1, 5.2, 5.3, 5.4, 6.1, 6.2, 6.3 и 7.1. Плюс к тому три версии Visual Studio (каждая из которых как в x86, так и в x64). Плюс две версии clang (3.9 и 4.0).

Под каждую версию компилятора у меня есть свой bat-файл, в котором настраиваются все пути и все окружение. И для каждого батничка свой ярлык на рабочем столе. Нужен мне, скажем, gcc-4.8, я кликаю на ярлык, попадаю в нужную среду, захожу в нужный мне каталог, запускаю ruby build.rb или ruby some/project/prj.rb. И все.

среда, 17 мая 2017 г.

[prog.thoughts] По мотивам одного из докладов с C++ CoreHard Spring 2017

На прошедшей на днях конференции C++ CoreHard Spring C++ был один весьма неоднозначный доклад. Это доклад Василия Вяжевича "Модульность и управляемая многопоточность встраиваемых С++ приложений — трудности, проблемы, решения". Доклад, пожалуй, самый слабый из всех докладов этой конференции. Тем не менее, если тема многопоточности в C++ интересна всерьез, то с докладом ознакомиться имеет смысл (если смотреть на youtube, то имеет смысл увеличить скорость до 1.25 или даже до 1.5, иначе слушать будет совсем грустно).

У меня впечатления от доклада, хоть и неоднозначные, но в большей степени негативные.

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

С другой стороны, нужно сказать две вещи, которые, предполагаю, пойдут в разрез с тем, что прозвучало в докладе.

Во-первых, многопоточность выбирается для реализации приложения не просто так. По крайнем мере, если мы говорим об опытных разработчиках, которые понимают, что делают, а не хватаются за std::thread просто потому, что только что прочитали об этом в документации. Как я уже неоднократно говорил, многопоточность используется либо для нужд parallel computing, либо для нужд concurrent computing. И в обоих случаях мы получаем сильно разную клиническую картину:

  • в случае parallel computing количество рабочих потоков у нас будет ограничиваться количеством вычислительных ядер. При этом мы заинтересованы в том, чтобы какой-либо обмен данными между рабочими потоками был сведен к самому минимуму. В идеале, рабочие потоки должно работать над совершенно независимыми и непересекающимися наборами данных. Поэтому отладка таких многопоточных приложений не так сложна, как это может показаться. Ведь каждая нить представляет из себя, по сути, небольшой самостоятельный однопоточный процесс, который очень мало взаимодействует с внешним миром. Следовательно, нас мало волнуют ситуации, когда параллельный поток убежал куда-то вперед или немного подотстал. Но самое главное другое: если у нас задача сократить общее время расчета (а для этого и нужен parallel computing), то мы можем использовать либо многопоточность, либо многопроцессность. И для одного, и для другого есть свои показания и протовопоказания. Но смысл в том, что для parallel computing в каких-то условиях выбор в пользу многопоточности будет единственно верным. И это не зависит о того, нравится ли нам многопоточность и умеем ли мы отлаживать многопоточный код;
  • в случае concurrent computing количество рабочих потоков ограничивается лишь степенью нашей распущенности :) Параллельные потоки в concurrent computing мы используем либо для того, чтобы снизить степень влияния одной независимой задачи на другую независимую задачу (например, запись в файл не должна блокировать запрос к БД), либо для того, чтобы упростить реализацию какой-то независимой задачи. Так, какую-то последовательность действий нам может быть проще записать в виде простой последовательности синхронных вызовов, чем делать то же самое посредством конечного-автомата с размазыванием логики между отдельными callback-ами. Проблем с многопоточностью в случае concurrent computing гораздо больше, поскольку:
    • нашим задачам, как правило, придется оперировать над какими-то общими разделяемыми данными. Соответственно, если это мутабельные данные, то у нас начинается головная боль по защите разделяемых мутабельных данных и по обеспечению их консистентности;
    • поскольку часть наших задач будет так или иначе зависеть друг от друга и взаимодействовать друг с другом, то нам важна будет синхронизация по времени в каких-то узловых точках. Т.е. если мы делаем задачу A, а параллельно выполняется задача B, результат которой когда-то потребуется в задаче A, то для нас может быть важно, чтобы задача B не затормозила и была выполнена до того момента, когда внутри A мы обратимся к результатам B.
    И вот все это в совокупности и приводит к тому, что отладка многопоточных приложений превращается в сплошной геморрой. Ведь нам приходится иметь дело и с разделяемыми мутабельными данными, которые могут поменяться в любой момент извне. И с "времянкой", когда параллельно выполняющиеся потоки либо сильно притормаживают, либо уходят далеко вперед.

Так вот проблема доклада Василия Вяжевича в том, что он не обозначил явным образом то, что речь будет идти только о специфике задач concurrent computing. И что представляемое слушателям решение возможно потому, что у задач из категории concurrent computing есть интересное свойство: зачастую им вообще не нужен параллелизм, можно обойтись квазипараллелизмом. Как раз то, что было в ранних версиях Windows 3.*, работавших в реальном режиме процессора.

Однако, для того, чтобы обеспечить работу множества задач на одной единственной рабочей нити, нам нужно сделать выбор между:

  • использованием какого-то из вариантов объекта с коллбэками. Т.е. есть объект, у которого некий фреймворк дергает тот или иной коллбэк. И работа фреймворка не может продолжиться, пока объект не вернет управление назад. По этому принципу работают самые распространенные акторные фрейворки для C++ (QP/C++, CAF, SObjectizer) и не только для C++ (например, Akka);
  • использование сопрограмм, которые фреймворк может приостанавливать и возобновлять. Например, когда из сопрограммы дергается какой-то вызов самого фреймворка и фреймворк получает возможность заморозить текущую сопрограмму и разморозить какую-то другую сопрограмму. По этому принципу работают, например, Boost.Fiber и Synca для C++.

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

Во-вторых, то, что показывал Василий Вяжевич в своем докладе, на мой взгляд, является отличной иллюстрацией того, о чем я говорил в конце своего доклада "Шишки, набитые за 15 лет использования акторов в C++":

...реализовать в своем фреймворке какую-то идею и показать ее работоспособность — это не так уж и сложно. Можно потратить несколько месяцев труда и получить вполне себе работающий и интересный инструмент. Это все делается на чистом энтузиазме. Буквально: понравилась идея, захотел и сделал.
А вот оснащение того, что получилось, всякими вспомогательными средствами, вроде сбора статистики или трассировки сообщений — это уже скучная рутина, на которую не так то и просто найти время и желание.

Вот мне бы не хотелось, чтобы у слушателей доклада возникло ощущение, что создание своего маленького фреймворчика для квазипараллельного обслуживания мелких задачек -- это хороший подход к решению проблем concurrent computing. Тут запросто можно получить то, что известно под названием "проблемы регулярных выражений":

У вас есть проблема. Вы думаете над ее решением и вам в голову приходит отличная мысль:
-- Да тут же можно использовать регулярные выражения!
Все. Теперь у вас есть две проблемы.

Вот так и с самодельными фреймворками для диспетчеризации задач. Вначале они решают ваши проблемы. Потом сами становятся вашими проблемами. Так что если вы сталкиваетесь с ситуацией, когда для concurrent computing вам нужно множество объектов-тасков с коллбэками, а так же какой-то диспетчер для них, посмотрите сперва по сторонам. Возможно, инструменты вроде QP/C++, CAF, SObjectizer или даже Intel TBB уже содержат то, что вам нужно. Уверяю, посмотреть по сторонам будет быстрее и дешевле, чем налабать на коленке что-то за пару дней, а потом саппортить это на протяжении нескольких лет, а то и дольше.

Кроме того, хоть я и сам без пиетета отношусь к формальному делению на какие-то модели, вроде Actor Model, CSP или что-то еще, но. Не могу не отметить, что когда признаки той или иной модели легко проявляются в некоем фреймворке, то гораздо проще понять, на что способен фреймворк и как этот фреймворк использовать. Так, если мне говорят про Actor Model, то это одни подходы к использованию. Если про CSP-шные каналы, то другие.

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


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

понедельник, 15 мая 2017 г.

[prog.c++] SObjectizer 5.5.19.1

Как оказалось, в коде SO-5 уже давным-давно жило несколько лишних точек с запятой, которые вызывали ошибку компиляции в gcc при совместном использовании ключей -Wpedantic и -Werror. Дабы устранить эту проблему мы сделали тег 5.5.19.1, в которой эти точки с запятой удалены. Код версии 5.5.19.1 собирается gcc и clang с ключами -Wpedantic и -Werror. Для gcc 6.* и 7.* может потребоваться добавить ключ -Wno-unused-function, иначе в одном из мест у gcc сносит крышу и он ругается на то, на что ругаться не должен.

Взять 5.5.19.1 можно либо из svn, либо с github-а, либо в виде архива с SourceForge.

На SourceForge ахив бинарников для Windows с версией 5.5.19.1 не делал, т.к. у Visual C++ подобных проблем не наблюдалось вообще. Но если кому-то нужно, то дайте знать, сделаем.

воскресенье, 14 мая 2017 г.

[life.photo] Эх, давно я не брал в руки шашек... Или краткие впечатления от съемки на зеркалку

Вчера подвернулся случай взять в руки и поснимать на большую чОрную зеркалку с большим чОрным и тяжелым объективом :) Спустя какое-то невероятно долгое время. Могу ошибаться, но думается, что последний раз я фотографировал что-то более-менее серьезное на цифрозеркалку около года назад, на "Дне красного носа 2016". А по сути, последние полтора года снимаю только на беззеркальную камеру Fujifilm x30. И кратковременное возвращение с беззеркалки на зеркалку -- это интересный опыт.

С одной стороны, берешь нормального размера камеру в руки и понимаешь, что это правильный рабочий инструмент, который десятилетиями затачивался под работу. Пусть он больше и тяжелее беззеркальной камеры, но зато лежит в руке как надо. Можно спокойно изготовиться и ждать подходящего момента для съемки не думая о том, что камеру держать неудобно. С маленькой беззеркалкой, даже если у нее есть нормальный видоискатель, так не получается. Так что в плане эргономики размер имеет значение :)

Качество картинки, которое выдает более-менее современный ФФ-сенсор и возможность беспрепятственно снимать на ISO выше 1000 после x30 -- это какой-то космос. Сложно передать насколько это все важно для репортажа, когда ты не контролируешь освещение и должен лупить кадры как пулемет, чтобы затем получился приличный фотоотчет из нескольких десятков хороших кадров (выбраковка при этом достигает более 90%, а времени на тщательную обработку оставшихся кадров нет).

Долгое время жизни аккумулятора. Более 500 отснятых кадров, просмотр их после съемки прямо на камере, сама камера постоянно включена более 5 часов подряд... И исчезла только одна рисочка из пяти на индикаторе заряда.

По сравнению с беззеркалкой у зеркалки всего один недостаток, но зато какой! Я уже привык, что в электронном видоискателе беззеркалки видно то, что будет и на итоговом снимке. Тогда как на зеркалке то, что ты видишь в видоискателе и то, что получится в итоге -- это две совсем разные вещи. И, когда снимаешь в условиях меняющегося света в полностью мануальном режиме, да еще увлечен поиском ракурса и момента, то не всегда обращаешь на небольшую подсказку о состоянии экспозиции. Тем более, что в сложных условиях эта подсказка сама врет.

Так что есть ощущение, что ТОПовая репортажная беззеркалка, появись такая на рынке, может в разы облегчить работу репортажного фотографа.


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

corehard_spring_2017_two_portraits

В очередной раз подумалось о том, что жил бы я в более крупном городе, хотя бы размером с Минск, можно было бы рискнуть и сделать что-то вроде "Студии негламурного портрета". Где целью съемки было бы не получение парадно-выходного или гламурно-отфотошопленного портрета, а попытка передачи характера или эмоции портретируемого. Что-то вроде "характерного портрета в профессиональном интерьере". Понятное дело, что это мало кому нужно. Но в большом городе это хотя бы можно было бы вывести в ноль. Т.е. рассматривать в качестве хобби, но не разорительного хобби. В маленьком же городе это вообще никому не понадобиться, как мне представляется.