|
0 / 0 / 0
Регистрация: 20.04.2020
Сообщений: 11
|
||||||||||||||||
Shared_ptr и парадигма CoW20.04.2020, 22:54. Показов 3431. Ответов 42
Метки нет (Все метки)
Задача:
Написать простенький аналог shared_ptr применяя парадигму Copy on Write. Проблема: Не могу понять в какой момент дергать функцию создания данных и как правильно это сделать. Как реализовать функции void ensureInitialized() const и void ensureUnique().
0
|
||||||||||||||||
| 20.04.2020, 22:54 | |
|
Ответы с готовыми решениями:
42
Парадигма программирования php Чистота Haskell и функциональная парадигма |
|
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|||
| 21.04.2020, 01:08 | |||
|
Добавлено через 4 минуты
0
|
|||
|
0 / 0 / 0
Регистрация: 20.04.2020
Сообщений: 11
|
||
| 21.04.2020, 01:08 [ТС] | ||
|
1) Дергается функция void DataUser::read() const 2) Внутри нее дергается const Data* DataHandler::operator ->() const 3) Внутри const Data* DataHandler::operator ->() const мы сначала дергаем void DataHandler::ensureInitialized() const, который в случае refCountrer == 0 создаст нам новый объект. То есть создать новый объект класса DataHandler, который дернет конструктор Data?
0
|
||
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
|||
| 21.04.2020, 01:12 | |||
|
Добавлено через 2 минуты
0
|
|||
|
0 / 0 / 0
Регистрация: 20.04.2020
Сообщений: 11
|
||
| 21.04.2020, 01:14 [ТС] | ||
|
Поэтому и обратился сюда за помощью.
0
|
||
|
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|||
| 21.04.2020, 01:16 | |||
|
Добавлено через 32 секунды Ailuropoda, применяй сразу к строкам. там это гораздо проще. там окромя крайне неэффективного варианта скопировать в неконстантном [] есть еще вариант вернуть из него прокси-обертку.
0
|
|||
|
0 / 0 / 0
Регистрация: 20.04.2020
Сообщений: 11
|
|||
| 21.04.2020, 01:22 [ТС] | |||
0
|
|||
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
||
| 21.04.2020, 01:22 | ||
|
0
|
||
|
0 / 0 / 0
Регистрация: 20.04.2020
Сообщений: 11
|
||
| 21.04.2020, 01:25 [ТС] | ||
|
Видимо я не понимаю "логику" данной задачи...
0
|
||
|
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|||
| 21.04.2020, 01:29 | |||
|
Добавлено через 3 минуты
0
|
|||
|
0 / 0 / 0
Регистрация: 20.04.2020
Сообщений: 11
|
|||||||||||||
| 21.04.2020, 01:37 [ТС] | |||||||||||||
0
|
|||||||||||||
|
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
||
| 21.04.2020, 01:46 | ||
|
А вообще почему для чего то кроме строк это в общем то бессмысленно - в строках все изменение буфера на который сылаются строка идет через методы самой строки а не буфера на который она ссылается и это элементарно обрабатывается. У произвольного объекта без оповещений с его стороны это сделать не удастся.
0
|
||
|
Комп_Оратор)
|
|||||||
| 21.04.2020, 02:06 | |||||||
Сообщение было отмечено Ailuropoda как решение
РешениеМожет
И общий вопрос. Вы уже писали умный указатель считающий ссылки? Если да, то остаётся понять, что выделение памяти для создания собственного объекта, должно происходить лишь при попытке изменения объекта. Это значит, что все читают одну книжку, но как только кто-то решает сделать пометку на полях, - идёт и покупает собственный экземпляр. С этого момента счётчик начинает работать и изменённый объект может стать новой разшаренной книжкой для какой-то группы клиентов. Вот и всё. Создавая новый объект нужно уйти красиво из прежней группы уменьшив счётчик если там ещё кто-то есть (>1), а если объект видит что он один остался то, можно вообще этому смарту не делать ни чего, - просто выполнять модифицирующую операцию и всё. А уж если в группе есть ещё по крайней мере один владелец (счётчик>1) - уменьшаем счетчик (я умер для этого объекта /император Нерон/) и делать данные выделяя память - записывая копию + модификация. И счетчик на старт (=1). Советую поиграть в ролевые игры с книжками, коврижками и прочими бутербродами. Может помочь) Что касается строк, то это имхо не важно. Вы же не в типе данных CoW будете доить. Вы смарте будете. Это значит, что любой тип данных будет жить в куче. Там и строки могут жить если вы захотите.
0
|
|||||||
|
0 / 0 / 0
Регистрация: 20.04.2020
Сообщений: 11
|
|
| 21.04.2020, 02:38 [ТС] | |
|
Большое спасибо за столь яркий пример!)
По поводу умного указателя, а тем более со счётчиком... Это первый опыт написания данного класса, как и первое знакомство с CoW. Просто с самого начала... Не могу понять в какой именно момент нам проверить есть ли у нас вообще "книга" и если ее нет, то необходимо создать и сделать инкремент счетчика. Когда вызывается метод read, то мы просто инкрементируем счётчик у datahandler. Когда вызывается метод write, мы создаём новый объект, и делаем инкремент у него, перед этим сделав дикремент счётчика у предыдущего объекта? Запутался в этих трёх классах, так ещё и Datahandler используется в классе Data... Вообщем полная каша.
0
|
|
|
Комп_Оратор)
|
||||||||
| 21.04.2020, 03:43 | ||||||||
|
Наподобие:
Спать надо идти) Завтра подумаю, может как-то через прокси и преобразование попробовать отловить намерение писать или читать (вызывать константный или неконстантный метод у содержимого) непосредственно на интерфейсе указателя - операторах * и -> ... Но боюсь, не выйдет. А через методы чтения/записи кривовато выходит. Однако лих ваш препод, если совместил 2 таких темы. Бог ему не судья. Он его уже и так обидел. Имхо.
0
|
||||||||
|
Вездепух
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,333
|
|||
| 21.04.2020, 04:21 | |||
|
Хорошим кандидатом/примером CoW может служить, например, std::string. std::string, как вы сами понимаете, можно реализовывать через reference-counting и CoW. В такой ситуации каждый std::string объект - это фактически вариация "shared_ptr". Но это именно std::string: всю работу с подлежащими данными вы выполняете через интерфейс std::string. То есть этот "shared_ptr" пропускает всю работу с данными через себя. Он точно знает, когда происходит изменение вверенных ему данных (кроме доступа через data() разумеется), и может разумно принимать решение о том, когда нужно сделать CoW.В случае абстрактного универсального shared_ptr ничего этого нет. И никакого осмысленного CoW тоже быть не может. Работа с данными, вверенными shared_ptr, возможна только напрямую (примерно как если бы мы с std::string всегда работали только через data()), что полностью исключает какое-то разумное CoW.То есть максимум, что вы сможете сделать - это по прямому запросу пользователя "отщеплять" конкретный экземпляр вверенных shared_ptr данных в уникальную копию, перед тем как делать write. Называть такое ручное "copy before write" термином CoW - профанация.
0
|
|||
|
Комп_Оратор)
|
||
| 21.04.2020, 11:02 | ||
|
Ночью надо спать.
Так или иначе, нельзя пытаться заставить Смартройнтер знать что-то специфическое о интерфейсе класса данных. Стало быть придётся использовать свои методы навродь: readWal/writeVal и readByPointer/writeByPointer а семантику указателей использовать на месте вызова, например. Не то что бы не здоровьем это попахивает, но непривычно - точно. И во всяком случае, это не то, что стоило совмещать с темой смарта с подсчётом ссылок. Это сама по себе не простая тема требует нового взгляда на весь копирующий, конструирующий/разрушающий функционал. Новый уровень понимания владения. Тема заслуживающая уважения, а следовательно - времени и усилий. Привет преподу)
0
|
||
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|||||||||
| 21.04.2020, 11:13 | |||||||||
|
"написать простенький" не получится. я это пишу, как программист, который уже делал подобные вещи. а с пониманием дизайна вообще. свой механизм я назвал "версионный указатель" (version_ptr) почему версионный? потому что через него можно получать доступ к данным, которые могут быть как в старой версии (до модификации), так и в новой (после модификации) дизайн использования:
rd() сокращение от read - доступ только для чтения. не приводит к созданию новой копии данных.wr() сокращение от write - доступ для записи. приводит к расщеплению данных.при этом cur1 и cur2 существуют одновременноих можно получить, например, в двух разных потоках один поток все временя только читает. а другой поток выполняет запись. читающий поток на самом деле будет вычитывать некоторую "старую" версию данных. в то время, как пишущий поток за счет COW, будет порождать и модифицировать "новую" версию данных. version_ptr специально разрабатывался для ситуации: когда есть 1 читатель, и множество писателей. что бы все они могли работать одновременно. ps персонаж под ником Fulcrum_013 похоже опять забыл принять свои лекарства. не предавай слишком большое значение тому, что он пишет. Добавлено через 41 секунду
0
|
|||||||||
| 21.04.2020, 11:50 | |
|
0
|
|
|
Комп_Оратор)
|
||
| 21.04.2020, 12:01 | ||
|
Ailuropoda, тут начинается взаимная диагностика, это к сожалению нормально. Однако все мы тут не раз слышали о указателях с обратными ссылками и это легко представить. Вы, желая изменить текст/рисунок или даже оглавление книги и вместо создания собственного поля деятельности, - говорите всем остальным смартам (у каждого из них есть ваш адрес - обратная ссылка) - а не пошли бы вы в магазин за новой книжкой. А уж если контейнеру нужно вычистить что-то (вектор не любит указателей внутрь - то есть к нему нужно итератором и его методом типа erase обращаться) то смарт должен контейнеры stl знать назубок. Или забыть в одночасье и написать свои.
Но время от времени мы это слышим и надо сказать, это полезно для раздумий о смысле самого смысла как такового в самом общем смысле этого смысла. Что касается CoW как инструмента этики (выше уже это было затронуто), то в развитие темы скажу, что не только разные потоки требуют этики. Этики требуют сами объекты. Ведь мы разделяем и властвуем изгоняя глобальные объекты и неконтролируемые зависимости не для того чтобы создать (лержитесь - новый термин) модель разделяемого представления (корова CoW - это оно, как разновидность), в которой каждый субъект понятия не имеет кто последний и как модифицировал данные. Представьте, что в классе есть указатель и один из коллективных любителей молока взял и сбросил его в ноль. Понос у него сегодня. Болеть будут все кто попытается разыменовать этот указатель.
0
|
||
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|||
| 21.04.2020, 13:18 | |||
|
вот это - факт. ты используешь слово "невозможно" для вполне осуществимых вещей. даже после того, как тебя ткнут рожей в рабочий код.
0
|
|||
| 21.04.2020, 13:18 | |
|
COW copy on write, класс MyString Описать класс Cow, который наследуется от класcа Animal
Создаем объект cow, у которого есть метод message, который принимает аргументом text и возвращает его
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ
Основная суть и тезисы по измерениям:
0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема.
Объект не может перемещаться в 0D.
1D (Первое измерение):. . .
|
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek
ВВЕДЕНИЕ
Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
|
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
|
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2.
Задача:
Обеспечить запись документа в регистр сведений независимо от. . .
|
|
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется.
Ну как вам?
|
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания
источниках данных и элементов формы(текстовые поля и метки), опирается все
это на технологию событий и мета. . .
|
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml,
в чате форсили функторы модулей как суперфичу.
Пытаясь отдуплить концепт, наткнулся на тутор с простым примером.
А главный принцип обучения от. . .
|
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
|