- надо было использовать WPF в каком-то известном приложении MS по маркетинговым причинам;
- архитектура Visual Studio, продолжашая эволюционировать с Visual C++6, начала мешать добавлению новых возможностей в студию.
понедельник, 22 февраля 2010 г.
WPF в Visual Studio 2010: причины
суббота, 6 февраля 2010 г.
Статья Саттера об асинхронном API
воскресенье, 27 декабря 2009 г.
Обработка событий - что и как получать?
В этом же посте хочу сосредоточится на таком небольшом пункте, как аргументы в функциях-обработчиках событий. Вещь-то сейчас кажется тривиальной, но надо посмотреть на грабли, которые заложили для нас предшественники. Итак поехали:
При обработке событий можно выделить 2 аспекта: как мы получаем событие и что мы получаем с событием вместе.
При получении событий от источника сообщений возможны следующие варианты:
- мы подписываемся отдельными потребителями на сообщения от соответствующих объектов источника
- мы подписываемся на сообщения от всей системы-источника сообщений(при этом можно указать, что такие-то события нам нужны, а такие-то нет, но источником событий у нас служит система целиком)
Причины приведённые выше будут влиять на архитектурные решения, какой из вариантов выбирать: вариант с целевой подпиской выгоден в пределах одной системы и нескольких подсистем(продукты одной фирмы будут прекрасным примером реализации доставки сообщений), вариант с общей подпиской выгоден при стыковке сильно разнородных систем (практически все стандартные протоколы: MAPI, TAPI и т.п.)
Но, в целом, особой разницы между ними нет, скорее это разграничение на количество каналов, по которым общаются система источник событий и система потребитель событий - если канал 1, то у нас вариант с общей подпиской, если несколько, то мы скорее всего имеем вариант с целевой подпиской. И выбор какой из этих 2-х вариантов реализовывать больше дело вкуса.
Примером варианта с целевой подпиской может служить реализация доставки событий в COM, а примером с общей подпиской - WinAPI.
При предоставлении дополнительной информации сейчас наибольшее распространение получили два подхода:
- мы передаём все данные о произошедшем событии в функцию обработчик события, надеясь, что разработчику будет в дальнейшем этого достаточно.
- мы ничего не передаём, кроме собственно самого извещения, что событие произошло - с надеждой что разработчик получит всю нужную ему информацию сам.
В варианте №1 ОЧЕНЬ часто забывают добавить константность для передаваемых параметров. И тогда следующий зарегистрированый обработчик может получить отнюдь не то, что ожидалось. И вообще, строить механизм вычислений с помощью обработчиков событий - не совсем хорошая идея ;)
Ещё одни тщательно разбросанные грабли (особенно их часто можно увидеть в КОМе) - это параметр, который контролирует будет ли отправлено сообщение следующему обработчику. Единственный вариант, когда это необходимо - это ситуация когда, событие в системе должно быть обработано не больше 1-го раза. В общем же случае, когда разработчик не знает кто зарегистрировался до/после него для обработки события, этот аргумент становится бесполезным или даже вредным - ибо становится возможным поломать поведение не только своей системы или системы источников событий, а и сторонних систем (на такие случаи мне везло в плагинах к Ворду :( ).
А самые заботливо укрытые грабли лежат в в варианте №2, когда общение между системой источником и системой потребителем идёт по 1-му каналу - заботливо укрывает эти грабли тот факт, что их не видно в однопоточном приложении. Но вот если в системе крутится несколько потоков, причём два и больше потоков могут отправлять события, то тут всё и начинается.
Пример:
Есть система с 2-я потоками, каждый из которых изменяет некоторую структуру данных в памяти, в целях потокобезопасности доступ к структуре закрыт критическими секциями, события отправляются после каждого изменения, но в целях быстродействия отправка событий сделана асинхронно. Потребитель событий должен забрать данные из этой же структуры данных - доступ опять же организован безопасно. На события подписан только 1 потребитель. В определённый момент времени происходит следующая ситуация: поток1 получил доступ к данным, успешно их поменял и отправил извещение, что он закончил работу; поток2 со спокойной цифровой душой получает доступ к данным, тоже их изменяет и тоже отправляет сообщение "всё ок - принимайте данные". Потребитель событий начинает забирать даныые по 1-му отправленому извещению, но то ли такт процессорный неудачно лёг, то ли sleep студент поставил, ну в общем не успел забрать данные до того как поток2 их изменил. И вот что делать в такой ситуации? - событие мы обрабатываем мы ещё 1-е, а данные уже лежат для 2-го события.
Т.е. у нас классический Data Race заботливо подготовленный системой, которая отправляет события.
Уменьшить вероятность проблем можно запустив отдельный поток, который будет обрабатывать сообщение и копировать структуру данных как можно ближе к моменту запуска сообщения. А функции-обработчики событий будут работать как в варианте №1. Но это не решит саму проблему с подходом №2 - просто уменьшит вероятность возникновения Data Race.
Выглядит описанная ситуация довольно надуманной, но это описание работы с реализацией TAPI от Cisco. :(
Как общее итого
не лениться и гонять всю необходимую инфу через параметры события - граблей меньше и они значительно менее опасны.
пятница, 13 ноября 2009 г.
Результаты October 2009 ISO C++ Standards Meeting
Общее итого: Афигеть!
Теперь по пунктам:
1. Стандарт так и не был не утверждён, и большая часть встречи была посвящена закрытию "тёмных углов". - Это понять можно. При этом, опять же, закрыли не все проблемные места. - А вот это уже понять сложно, т.к. разработчики C++ компиляторов уже начали наступать на эти грабли (для примера можно посмотреть объяснения от MS VC++ Team - почему они в срочном порядке доделывали null_ptr в своей бете2 студии 2010).
2. Следующая встреча в марте 2010 года. Посвящена будет оставшимся проблемным местам в стандарте. Вот не понял, зачем было откладывать на полгода - что ещё осталось шлифовать? Ладно, я ещё могу понять Python с их PEP3003, ибо надо чтобы альтернативные реализации догнали основную и наиболее популярные библиотеки вышли уже с поддержкой Python3. Но что хочет дождаться комитет для C++ - просто не понимаю...
3. Они умудрились потерять главного, по их же словам, организатора и текущего председателя комитета P.J. Plauger, который к тому же был самым опытным среди них во взаимодействии с ISO. При этом он не выдержал обычного 3-хлетнего срока - вот это понять даже сложнее, чем просто уход с поста председателя из-за перевыборов. О замене даже не договорились, хотя вызывается добровольцем Саттер, как председательствовавший предыдущие 2 срока. Но это немного не тот человека из-за того, что активная фаза создания стандарта уже закончена и надо заниматься политикой, а не разработкой.
С учётом вышеизложенного, текущих темпов, того, что на мартовской встрече понадобится закрыть баги и неясности, которые остались открыты после этой встречи, и если будет предложение очередной "новой маленькой" фичи, то как бы стандарт не стал C++0xB или даже C++0xC. Хотя в последнем есть своя суровая гармония. :(
P.S.
В этом свете, хорошо, что выбросили концепты. Плохо, что их не выбросили раньше и потратили на них время, которое могло быть потрачено с большей пользой на что-то другое. Хотя концепты, конечно, очень жаль именно как идею и то, что за ней стоит.
среда, 21 октября 2009 г.
Блог Саттера: Опрос
В целом его блог для программистов на C++ из набора "очень желательны к ознакомлению". А цикл статей "Effective Concurrency" - это уже из набора "обязательных к прочтению", - 90% вопросов, которые возникают в процессе работы и на собеседованиях уже освещены.
Очень советую к прочтению.
P.S.
Вот и как на русский перевести правильно concurrency programming?.. Многопоточное и конкурентное программирование это всё же другие оттенки смысла.
четверг, 15 октября 2009 г.
Сортировки и сборки...
понедельник, 28 сентября 2009 г.
Unicode - Питон, PyQt, XML
суббота, 26 сентября 2009 г.
No Time for JAVA
I've tried Pascal, time after time
I've done my COBOL but committed no crime
C pointer mistakes, I've made a few
I've had my share of Lisp and Haskel and Scheme but I still haven't a Clu
(and on and on and on and on)
We are the champions, O Bjarne!
And we'll keep compiling till the end
You've made us champions, we are the champions
No time for Java 'cause we are the champions
Of the world!
I've taken my macros, and my function calls
I've enjoyed speed and performance and everything that goes with C, I love them all
But C's been no bed of roses, and Ada's no pleasure cruise
I want abstraction and optimization both, so I ain't gonna use...
(and on and on and on and on)
среда, 26 августа 2009 г.
Популяризатор
Оформилось при написании предыдущего поста и разрослось в отдельный пост.
В C++ есть очень много возможностей/фич, которые в связке могут давать больший выигрыш, чем каждое по отдельности – т.е. существуют некие наборы, для которых 2+2=5. Что-то наподобие паттернов, только на языковом уровне. Мне самому это находить пока навык не позволяет, только разве что почувствовать, что оно где-то рядом. Как пример того, что может дать больший полезный выхлоп чем кажется начально: лямбды и стандартные алгоритмы, Valarray, срезы и обработка больших массивов данных…
Но Community C++ сильно нехватает Популяризатора – да, именно популяризатора с большой буквы. Причём не только русскоязычному, а и мировому.
Нет человека, который выступил бы в некотором роде “локомотивом” для C++. У Python есть Гвидо ван Россум, у C# - Microsoft целиком, даже у Java есть(был?) Sun, который раскручивал этот язык.
А у C++ никого/ничего подобного нет: Страуструп ушёл в развитие возможностей языка, Эккель сам говорит, что его больше интересует Python по различным причинам, Александреску заблудился в “лабиринтах шаблонов”, Майерс – где-то рядом с Александреску ( пока… - хотя тут возможен вариант), Степанов – ближе к научному программированию, Саттер – он подходит больше всех сейчас на роль популяризатора , но у него, уже на момент публикации “Free lunch is over” в 2003, оформилась многопоточность и всё с ней связанное, как основной приоритет. Т.е. Личности в Community C++ есть, но нет именно Популяризатора.
А ведь ситуация сейчас складывается довольно выгодная для C++: выросший рынок мульти-платформенных приложений с появлением сильного Qt может быть почти полностью привязаться к C++ на ближайшие 5-10 лет, постоянно растущий рынок embedded с его требованиями к эффективности склонен использовать C++, а не Java, C#, Python и иже с ними.
И вот хотелось бы найти Популяризатора, который смог бы раскручивать язык и использовать для этого в том числе и “языковые паттерны”.
Философия С++. Брюс Эккель.
По прочтении “Философия С++” Брюса Эккеля оформилось несколько мыслей, которые собственно и попытаюсь сформулировать.
Основная мысль - Раньше её надо было прочитать, значительно раньше! Хотя бы сразу после “Паттерны проектирования” GoF. Ибо глава посвященная петтернам у Эккеля кроме собственно объяснений паттернов содержит реализацию паттернов на C++ и критику по паттернам. Т.е. позволяет паттерны хорошо утрясти в голове. При чём эккелевские примеры реализации содержат часто моменты, которые не видны при реализации “в лоб” при переносе оригинала с Java – соответственно мог переступить через несколько граблей, а не проверять их своим лбом. :(
Возможности языка, которыми не владеешь хорошо, склонен рассматривать как зло предварительной оптимизации. А как только овладеваешь ими на уровне “Conscious Competence”, то уже перестаёшь понимать почему ты раньше так их боялся.
- В таблице моё впечатление от отдельных глав – насколько стоило их читать, т.е. что они позволяют достичь
| Том/Глава | Что позволяет сделать |
Том 1 | повторить основы |
| Том 2 | |
| Главы 1-4 | повторить основы |
| Глава 5: Templates in Depth | Вдумчиво разобраться с механизмом |
| Глава 6-7: Generic Algorithms and Containers | Очень вдумчиво разобраться с описаными механизмами |
| Главы 8-9 | повторить основы |
| Глава 10: Design Patterns | Очень вдумчиво разобраться |
| Глава 11: Concurrency | Прочитать для интереса, за исключением Summary, которое стоит вдумчиво разобрать. Всё равно у Саттера лучше. |
Да, C++Primer я читал – пока кажется “предварительной оптимизацией” ;)