Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.129.210.17] |
|
Страницы: (16) « Первая ... 2 3 [4] 5 6 ... 15 16 все ( Перейти к последнему сообщению ) |
Сообщ.
#46
,
|
|
|
Нет, не так. Здесь первый поток ресетит shared_ptr, sp, и присваивает его weak_ptr'у, sp2. Второй поток вызывает weak_ptr::lock, те создаёт новый shared_ptr, и, если он не null, обращается к его содержимому. Для std::shared_ptr это не работает, для CSharedPtr всё нормально
|
Сообщ.
#47
,
|
|
|
Олег М, вот какая проблема с многопотоковостью SP.
1. Несколько экземпляров SP указывают на объект выбранного типа. 2. Другие несколько экземпляров - на другой объект этого-же типа. 3. SP - это шаблонный класс. Значит, возможно наличие групп SP, указывающих на объекты любых других типов. Необходимо, чтобы потоко-безопасность обеспечивалась для каждой группы отдельно. Иначе манипуляции со счётчиком ссылок одной группы будут влиять на манипуляциями со счётчиками любой другой группы SP. А это как раз и не очень хорошо. |
Сообщ.
#48
,
|
|
|
Цитата Олег М @ Нет, не так. Смотри. Строчка 9: - ты передаёшь в поток оба указателя по ссылке. Строчка 13: Цитата Олег М @ sp.reset(new std::string("!!!!!!!!!!!!!!!!!!!!!!!!!!!!11111111111111111111111111111111111111")); Ты в нескольких потока одновременно модифицируешь один и тот же shared_ptr. То есть незащищённый конкурентный доступ к внешнему ресурсу. Строчка 14: Ты так же конкурентно (как и в предыдущей строке) модифицируешь разделяемый weak_ptr. Один и тот же во всех потоках. Строчка 18: Передаёшь ещё в один поток ссылку на внешний weak_ptr. Строчка 18: Пытаешься залочить внешний weak_ptr, который активно (без синхронизации) меняется из соседнего потока. Ты, конечно, можешь ожидать, что будет создана отдельная копия shared_ptr'а на какой-то указатель, но если повезёт, твоя программа свалится с внятной диагностикой. Ибо тут самый что ни наесть типовой data race. Если не повезёт - отправится SMS на адрес Трампа и он нажмёт на красную кнопку в своём ядерном чемоданчике. Undefined Behavior - он такой. |
Сообщ.
#49
,
|
|
|
Имеешь ввиду template <typename T> CSharedPtrLock &GetSharedPtrLock() и, соответственно, CSharedPtrBase::GetSharedRef()?
Добавлено Flex Ferrum Цитата Flex Ferrum @ Ты, конечно, можешь ожидать, что будет создана отдельная копия shared_ptr'а на какой-то указатель, но если повезёт, твоя программа свалится с внятной диагностикой. Ибо тут самый что ни наесть типовой data race. Если не повезёт - отправится SMS на адрес Трампа и он нажмёт на красную кнопку в своём ядерном чемоданчике. Undefined Behavior - он такой. Ну, во-первых не сваливается, работает. Во-вторых как раз эти функции и являются потоко-безопасными. Я там не ожидаю, я точно знаю, что будет создано return CSharedPtr<T>(GetSharedRef<T>()); Добавлено ЫукпШ Имеешь ввиду template <typename T> CSharedPtrLock &GetSharedPtrLock() и, соответственно, CSharedPtrBase::GetSharedRef()? Очень похоже на адский косяк, сижу, думаю |
Сообщ.
#50
,
|
|
|
Цитата Олег М @ Ну, во-первых не сваливается, работает. Я говорю про работу с shared_ptr. Как аргумент к тому, что конкретно этот пример разделяемым ресурсом считает сам указатель (CSharedPtr/CWeakPtr в твоей терминологии), а не CSharedPtrBase. |
Сообщ.
#51
,
|
|
|
Цитата Олег М @ Пытаешься залочить внешний weak_ptr, который активно (без синхронизации) меняется из соседнего потока. Вообще, там вроде всё синхронизируется, в конструкторах/деструкторах |
Сообщ.
#52
,
|
|
|
Цитата Олег М @ Вообще, там вроде всё синхронизируется, в конструкторах/деструкторах В стандартном? Нет. Не лочится. И не должно - это не требуется стандартом. А работа с атомиками (как я уже говорил) - это не локи. Это просто работа с атомиками. |
Сообщ.
#53
,
|
|
|
Цитата Олег М @ Я говорю про работу с shared_ptr. Как аргумент к тому, что конкретно этот пример разделяемым ресурсом считает сам указатель (CSharedPtr/CWeakPtr в твоей терминологии), а не CSharedPtrBase. Доступ к самому указателю синхронизируется при помощи счётчика CSharedCounter. Что именно неправильно, и как должно быть? Добавлено Цитата Flex Ferrum @ В стандартном? Нет. Не лочится. И не должно - это не требуется стандартом. А работа с атомиками (как я уже говорил) - это не локи. Это просто работа с атомиками. В стандартном да, не работает. Я где-то видел, что они планируют, сходу не могу найти где. У меня вроде работает. Работа с атомиками - это lock-free блокировка, чем то-хуже, чем-то лучше мьютексов. |
Сообщ.
#54
,
|
|
|
Цитата Олег М @ Доступ к самому указателю синхронизируется при помощи счётчика CSharedCounter. Что именно неправильно, и как должно быть? Ещё раз: я говорю про работу этого кода с std::shared_ptr/std::weak_ptr. Добавлено Цитата Олег М @ В стандартном да, не работает. Я где-то видел, что они планируют, сходу не могу найти где. У меня вроде работает. Работа с атомиками - это lock-free блокировка, чем то-хуже, чем-то лучше мьютексов. Работа с атомиками - это работа с атомиками. То есть работа с памятью с учётом особенностей многопоточной и многопроцессорной среды. Но не более того. Рассматривать это как блокировку (или варианты блокировки) - это обманывать самого себя. |
Сообщ.
#55
,
|
|
|
Цитата Flex Ferrum @ Ещё раз: я говорю про работу этого кода с std::shared_ptr/std::weak_ptr. Я ж вроде и говорил, что он не работает, именно поэтому пришлось писать свои классы. И? |
Сообщ.
#56
,
|
|
|
Цитата Олег М @ И? Я до сих пор не догоняю, какая именно реальная задача решается таким вот сценарием: Цитата Олег М @ Здесь первый поток ресетит shared_ptr, sp, и присваивает его weak_ptr'у, sp2. Второй поток вызывает weak_ptr::lock, те создаёт новый shared_ptr, и, если он не null, обращается к его содержимому. Для std::shared_ptr это не работает, для CSharedPtr всё нормально |
Сообщ.
#57
,
|
|
|
Цитата Flex Ferrum @ Работа с атомиками - это работа с атомиками. То есть работа с памятью с учётом особенностей многопоточной и многопроцессорной среды. Но не более того. Рассматривать это как блокировку (или варианты блокировки) - это обманывать самого себя. Ну почему обманывать, у lock-free алгоритмов есть масса преимуществ, особенно на многопроцессорных серверах. Есть и свои недостатки. Я в них не особо разбираюсь, поэтому в данном случае мне больше нравится, что они занимают много меньше памяти - 8 байт против 40 для мьютекса Добавлено Реальная задача чуть позже. Надо как-то сформулировать. Запустил-таки всю эту бадягу на боевом сервере, наблюдаю, не могу толком ни на чём другом сосредоточиться |
Сообщ.
#58
,
|
|
|
Цитата Олег М @ Ну почему обманывать, у lock-free алгоритмов есть масса преимуществ, особенно на многопроцессорных серверах. lock-free-алгоритмы - это одно из средств применения атомиков. Причём весьма специфичная. Средствами синхронизации атомики от этого не становятся. |
Сообщ.
#59
,
|
|
|
Почему? Есть возможность сделать так, чтоб один поток, подождал пока другой поток не освободил ресурс. Это ли не синхронизация?
|
Сообщ.
#60
,
|
|
|
Цитата Олег М @ Почему? Есть возможность сделать так, чтоб один поток, подождал пока другой поток не освободил ресурс. Это ли не синхронизация? Даже если ты делаешь синхронизацию на спинлоках - это все равно лочка, и алгоритм с такой синхронизацией lock-free назвать уже нельзя. |