[C++] спецификация многопоточности - часть интерфейса?
1) блокировка мьютекса осуществляется на неопределенное время, это считается плохи тоном (кстати, я пока не очень проникся этим утверждением, многие утверждают, что мьютексы надо держать как можно меньше времени)Чем тут проникаться? Если у тебя мутекс долго занят, то какой смысл от многопоточности вообще?
Конечно, надо разжимать как только не нужна синхронизация.
2) причина этого поста: классы StandardObjectAccessor и ThreadSafeObjectAccessor по-разному реализуют интерфейс и тем самым нарушается LSPИнтерфейсы созданы, чтобы их по-разному реализовывать
Вообще LSP о другом: он о связи между типом и подтипом, а не между подтипами общего типа.
К тому же он довольно формальный: ограничения на состояние типа не должно усиливаться при применении той же операции к подтипу.
Но если интерфейс не закрепляет этого, то могут появиться и потокобезопасные реализации, в чем проблема-то? Если это проблема, то ты по сути заявляешь следующее: "вот есть интерфейс, но если его реализация не испытывает проблем в многопоточной среде, то это уже не есть реализация этого интерфейса, это какая-то маргинальная, нехорошая реализация. Даешь только потокоопасные реализации!"
2) считаете ли вы, что необходимо описать как данный интерфейс (точнее, объект, реализующий этот интерфейс) можно использовать в многопоточной среде?имхо имееют право на жизнь оба варинта (определение поведение в многопоточности включаются в интерфес или не включается) и в разных проектах может быть удобней договориваться по-разному (как и для разных интефейсов в пределах одного проекта)
В случае включения имхо возможна и предложенная реализация (которая может не подойти из-за вопросов производительности, а может и подойти, зависит от ситуации)
1. Я думаю, что использоваться интерфейс будет только однопоточно.
2. Я знаю, что он предназначен специально для многопоточности.
А смешанных обычно не было.
После прочтения статьи про использование volatile для спецификации потокобезопасных интерфейсов http://www.ddj.com/cpp/184403766 (за что отдельное спасибо un...lu) я решил, что это удобный способ разделать потокобезопасные реализации от непотокобезопасных (как раз тогда понадобились интерфейсы, которые могут быть использованы и так и так). В самом примитивном случае можно сделать заглушку через мьютекс, когда одна ф-я использует другую, но чаще можно что-то более эффективное придумать.
Т.ч. теперь неспецифицированный интерфейс предназначен только для однопоточного использования, только с volatile - только для многопоточного (конечно, никто не мешает и из одного потока его вызывать если в интерфейсе есть оба метода - тогда вызывай как хочешь
Считаю, что это в определенный момент сильно упростили мне жизнь. Не приходится однажды ахнуть, поняв, что реализация не рассчитана на многопоточное использование, а используется.
Исключения в коде не специфицирую (через средства языка но пишу в документации. Не все, а только в данном методе которые напрямую могут произойти.
Чем тут проникаться? Если у тебя мутекс долго занят, то какой смысл от многопоточности вообще?мьютекс обеспечивает mutual exclusive access к ресурсу. именно из этого определения я исхожу, когда рассуждаю о необоснованной фразы "нужно отпускать как можно раньше". прагматичные вопросы перформанса не относятся к концептуальной целостности и непротиворечивости понятия мьютекса и не следует ими оперировать.
Интерфейсы созданы, чтобы их по-разному реализовыватьвремя бежит вперед и люди стали задумываться, как не наступать на одни и те же грабли и как повысить качество кода, а всякие понятия типа OCP, LSP придумали не от хорошей жизни. поэтому это слишком примитивный подход
Вообще LSP о другом: он о связи между типом и подтипом, а не между подтипами общего типа.формальность его изначально была ограничена абстрактными данными, но затем смогли найти удачную проекцию на практику (в частности, грамотное проектирование систем)
К тому же он довольно формальный: ограничения на состояние типа не должно усиливаться при применении той же операции к подтипу.
http://en.wikipedia.org/wiki/Behavioral_subtyping
http://www.objectmentor.com/resources/articles/lsp.pdf
цитата из pdf:
In order for the LSP to hold, and with it the Open-Closed principle, all derivatives
must conform to the behavior that clients expect of the base classes that they use.
мьютекс обеспечивает mutual exclusive access к ресурсу. именно из этого определения я исхожу, когда рассуждаю о необоснованной фразы "нужно отпускать как можно раньше". прагматичные вопросы перформанса не относятся к концептуальной целостности и непротиворечивости понятия мьютекса и не следует ими оперировать.а сразу это сказать слабо было? Если «прагматичными вопросами перформанса» (кстати, почему некоторые слова ты транслитерируешь, а некоторые — нет?) не задаваться, то можно дальше перестать задаваться и вопросами здравого смысла и как раз начать спорить ни о чем.
Поясни тогда постановку вопроса про мьютексы. Только так, чтобы потом не пришлось добавлять новые правила, как ты только что сделал.
Даже в твоей постановке: ну за хрень, у меня данные оказываются надолго недоступными? Это по-твоему нормально? Проникайся.
время бежит вперед и люди стали задумываться, как не наступать на одни и те же грабли и как повысить качество кода, а всякие понятия типа OCP, LSP придумали не от хорошей жизни. поэтому это слишком примитивный подходкакой подход? Да, примитивно говорить как ты: «интерфейсы реализованы по-разному, это плохо». Сам подумай. Зачем тогда вообще две реализации? Абсурд.
формальность его изначально была ограничена абстрактными данными, но затем смогли найти удачную проекцию на практику (в частности, грамотное проектирование систем)Это я все читал. Только вот ты ожидаешь от этих принципов какой-то магической силы, которая вмиг решит все твои проблемы. А решать-то самому надо. Так вот: почему ты решил, что клиенты не «ожидают» потокобезопасного поведения какой-то реализации интерфейса?
http://en.wikipedia.org/wiki/Behavioral_subtyping
http://www.objectmentor.com/resources/articles/lsp.pdf
цитата из pdf:
In order for the LSP to hold, and with it the Open-Closed principle, all derivatives
must conform to the behavior that clients expect of the base classes that they use.
статью почитал, в целом положительное впечатление, хотя в плане подхода к синхронизация есть пробелы у Александреску (можно почитать баталии на рсдн о мемори барьерах, сиквенс пойнтах, балансе между мьютесами и волатайлом и как все это работает на SMP)
использует захват мьютекса на неопределенное время (возможно, в угоду более светлой цели) и не стесняется говорить, что решая проблему с многопоточным доступом к ресурсам, приходится встречаться с дедлоками (оно и неудивительно, ибо буздумная блокировка мьютексов, порожденная введением "удобного класса", будет приводить к дедлокам)
использование квалификатора volatile в интерфейсах для подчеркивания особенности контракта мне кажется интересной идеей
Не приходится однажды ахнуть, поняв, что реализация не рассчитана на многопоточное использование, а используется.собственно, эти моменты хотелось бы исключить путем создания грамотных систем и мои вопросы следует рассматривать именно с этой колокольни.
возможные исключения мы тоже документируем без использования средств языка
интерфейсы реализованы по-разному, это плохопроцитирую избитую фразу: интерфейс описывает "что", а имплементация - "как"
две реализации - это хорошо, если они делает одно и то же "что", задекларированное так, чтобы клиент осознавал все возможные последствия
интерфейсы хороши нынче используют для минимизации зависимости между модулями, именно благодаря им стали создавать легко расширяемые и модифицируемые системы, однако, как мне кажется, без описания в интерфейсе такого распространенного качества, как потокобезопасность, система будет плохо модифицироваться и кубики в этом конструкторе тяжело будет заменить.
статья очень клевая, аж захотелось снова на С++ пописать =)
Это один подход. Можно создать вообще два разных интерфейса (ну как в .NET любят делать константные интерфейсы). Это другой. Где проблема?
Еще раз: вот мы с сказали, что да, можно требовать потокобезопасности, а можно не требовать. Что тебе тут не нравится? Имхо, вопрос исчерпан, никто не заставит меня требовать от интерфейса потокоопасности.
Оставить комментарий
Maurog
под интерфейсом мы будем понимать класс с чисто виртуальными функциями1) считаете ли вы, что необходимо описать (задокументировать) множество исключений, которое может кинуть каждый метод?
2) считаете ли вы, что необходимо описать как данный интерфейс (точнее, объект, реализующий этот интерфейс) можно использовать в многопоточной среде?
интерфейс - это ограничение и это ограничение мне больше нравится называть "контрактом".
вопросы родились в споре, а истина пока не "родилась"
рассмотрим пример:
имеется интерфейс (персонажи вымышлены)
имеется некая имплементация StandardObjectAccessor, которая адекватно работает в однопоточной среде
написан следующий декоратор
и предоставлена функция для создания потокобезопасного accessor-a из незащищенного:
чем хорош класс ThreadSafeObjectAccessor:
1) ответственность по блокировкам вытащена в отдельный класс и не перемешана с основной логикой чтения и записи объекта (привет SRP)
чем плох:
1) блокировка мьютекса осуществляется на неопределенное время, это считается плохи тоном (кстати, я пока не очень проникся этим утверждением, многие утверждают, что мьютексы надо держать как можно меньше времени)
2) причина этого поста: классы StandardObjectAccessor и ThreadSafeObjectAccessor по-разному реализуют интерфейс и тем самым нарушается LSP
аргументы: набор модулей стыкуется по швам - интерфейсам, тем самым повышается модифицируемость, гибкость. модули могут быть многопоточными, именно поэтому они должны четко представлять как можно использовать объекты с данным интерфейсом. только в этом случае можно будет применить OCP, LSP
контраргументы: контракт описывает поведение в однопоточной среде, не более. модуль должен знать качество (потокобезопасен ли) объекта, с которым он работает
приведу цитату из книги "Архитектура программного обеспечения на практике, 2-е издание"
как вы понимаете эту цитату? следует ли делать допущения про имплементацию? или здесь о чем-то другом?