Здравствуйте, T4r4sB, Вы писали:
TB>·>Сырой указатель — опасно. TB>Если ты знаешь, что хозяин дохнет позже пользователей, то нет.
А как узнать-то? Особенно в случае сложной системы, код которой постоянно меняется толпой программистов?
TB>·> И опять же — какие сигналы? Опять локи? TB>На передачу указателей локов не надо.
Я имею в виду, что "сигнал" это тоже нечто передаваемое между тредами — и тоже не даётся бесплатно и обычно содержит локи внутри.
TB>А вот при одновременном обращении к содержимому указателя — возможно, локи нужны, как и в жабе и в шарпе.
Зачем же локи-то... Есть же volatile, happens-before, atomic и прочие вкусности.
Да и, скажем, в жабе-шарпе есть иммутабельные классы, которые безопасно использовать всегда без всяких оговорок. В C++ они принципиально невозможны из-за наличия деструктора, не говоря уж о const_cast и почри памяти.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
I>>·>Короче, может и можно писать low latency на C++, но сложнее на порядок. I>>Испокон веков писали на С++, даже ОС реального времени наклепали десятками для таких случаев. ·>Испоконнее — pure C или даже ассемблер. Но традиция — не аргумент.
Ассемблер — очень смешно.
·>Нет гарантии и в случае с умными указателями, что освобождение заковыристого графа не нарвётся на lock или тупо будет работать долго, например, удаление одного объекта вызвало разрушение целой толпы других, gc же может съесть слона по кусочкам. А вообще есть Zing JVM и прочие RT GC. Задежка GC более 10ms — репортим баг.
Умный указатель это решается легко и руками.
lock — в low latency никто такое не имплементит изначально
"удаление одного объекта вызвало разрушение целой толпы других" —
а 1 в 1 как в джаве, только проблемы переносятся на GC
б 1 в 1 как в джаве, если разрушение это не просто занулени, а еще небольшая логика
в если убрать сматрпоинтеры, что часто даже лучше чем в джаве
Итого — на плюсах как минимум не хуже
GC ты вообще не контролируешь, никак и гарантии у тебя сильно хилые.
ну конечно попутал... ))) I>Ага, понял, ты нашел доказательство, что дотнетных OR/M нет вещей, которые должны быть в OR/M искаропки ? I>Есть целый форум на данном сайте, посвящен таким вот вопросам. Сходи туда, если ты хотел выяснить вопрос.
Мне это не нужно) Это я так, напомнил просто, что не всё так однозначно. )))
I>>>Это слишком древняя фраза, что бы пользоваться её без оглядки. _>>Я думаю она справедлива для всего инженерного дела, одним из подвидов которого и является программирование. I>И это чушь. Красота, как эстетическое, сильно субъективна, фактически — мода. Сегодня самолёты красивы, а завтра скажут, что это тупорылые огурцы. Из этого не следует, что самолеты должны задним числом перестать летать.
Истинная красота (которая гармония) не особо субъективна) А частенько может быть вообще выражена математическими выражениями.
I>Так и в программировании, когда ты сидел носом в С++, естетсвенно, тебе ничего кроме с++ не покажется красивым.
Я думаю что на любом вменяемом языке (не брейнфаке) можно написать и красиво и ужасно. А вот написать красиво и при этом одновременно получить максимально быстрый код можно далеко не на каждом языке.
Здравствуйте, alex_public, Вы писали:
I>>Ага, понял, ты нашел доказательство, что дотнетных OR/M нет вещей, которые должны быть в OR/M искаропки ? I>>Есть целый форум на данном сайте, посвящен таким вот вопросам. Сходи туда, если ты хотел выяснить вопрос.
_>Мне это не нужно) Это я так, напомнил просто, что не всё так однозначно. )))
Здесь нет никакой неоднозначности а просто отсутствие вижлы в конкретный момент времени. На таких вот моментах ты и строишь свои "теории".
Сейчас у меня тоже нет вижлы и соответственно, ничего я тебе не покажу, даже на счет 2+2. Прикинь, какой вывод можно сделать: "Сенсация ! Дотнет не умеет 2+2 !!!!11одинодин"
I>>И это чушь. Красота, как эстетическое, сильно субъективна, фактически — мода. Сегодня самолёты красивы, а завтра скажут, что это тупорылые огурцы. Из этого не следует, что самолеты должны задним числом перестать летать.
_>Истинная красота (которая гармония) не особо субъективна) А частенько может быть вообще выражена математическими выражениями.
Вообще то субъективна. У разных культур разное представление о красоте и гармонии.
I>>Так и в программировании, когда ты сидел носом в С++, естетсвенно, тебе ничего кроме с++ не покажется красивым. _>Я думаю что на любом вменяемом языке (не брейнфаке) можно написать и красиво и ужасно. А вот написать красиво и при этом одновременно получить максимально быстрый код можно далеко не на каждом языке.
Ну да, за неимением формулировки "красота" надо просто повторять "красиво" и всё станет красиво, ага.
Здравствуйте, ·, Вы писали:
_>>shared pointer нужен в случае параллельного доступа к данным из разных потоков с неизвестным заранее временем жизни. Это совсем не частный случай даже в системах с подобным параллельным доступом. А если использовать более продуманные архитектуры (типа той же модели акторов), то подобные вопросы не встают в принципе. Тем более, что при использование семантики перемещения модель акторов становится такой же эффективной, как и просто общая память (в варианте без блокировок). ·>Это не частный случай, а наиболее простая имплементация. Конечно, можно внимательно изучить, установить время жизни каждого объектика, но это сложно контролировать и тестировать, а в случае ошибки — undefined behaviour. В случае же java — самое страшное что будет — это latency spike из-за garbage collection, а не порча данных, как в случае ошибок с указателями.
Ничего подобного. Ты путаешь время жизни объектов и время жизни потоков. Вот смотри, допустим у нас есть главный поток (не обязательно по приложению, а скажем по задачке некой), который порождает N других потоков, с которыми взаимодействует через общую память (не факт что лучшее решение, но раз ты его хочешь, то давай обсудим). Для этого достаточно выделить память в главном потоке и хранить её как unique_ptr (или вообще просто объявить локальную переменную, что заметно удобнее). А дочерним потокам передать голый указатель (или вообще ссылку, что заметно удобнее) на эти данные. Такая система будет 100% безопасна в случае гарантий завершения дочерних потоков раньше главного. Если подобные гарантии не следуют из логики задачи, то их можно легко получить ручным способом, разместив в конце главного потока код ожидания (банальный thread.join() в случае C++) завершения дочерних потоков.
Так что, как видишь, у нас нет никаких намёков на необходимость использования shared_ptr для реализации взаимодействия потоков через общую память.
·>Модель акторов — в первую очередь для упрощения параллелизма, а не low latency.
Всё правильно, упрощение. Которое при этом обеспечивает ещё и гарантию безопасности (которую в случае модели общей памяти надо достигать локами, в любом языке программирования) взаимодействия потоков. Ну а при правильной реализации можно получить ещё и быстродействие не хуже модели общей памяти.
Здравствуйте, ·, Вы писали:
·>А как узнать-то? Особенно в случае сложной системы, код которой постоянно меняется толпой программистов?
В случае бардака — никак.
·>Я имею в виду, что "сигнал" это тоже нечто передаваемое между тредами — и тоже не даётся бесплатно и обычно содержит локи внутри.
Сигнал о конце работы вряд ли создаст проблему производительности.
·>Зачем же локи-то... Есть же volatile, happens-before, atomic и прочие вкусности. ·>Да и, скажем, в жабе-шарпе есть иммутабельные классы, которые безопасно использовать всегда без всяких оговорок. В C++ они принципиально невозможны из-за наличия деструктора, не говоря уж о const_cast и почри памяти.
Если уж говорить про const_cast, то я могу сказать, что в жабе можно сделать так, что 2*2=5. Это тоже правда, и это тоже наброс.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, Serginio1, Вы писали:
_>>Эту библиотеку мало используют, потому что она только недавно появилась на свет. Если тебя интересуют популярные и проверенные временем ORM решения на C++ то смотри: _>>1. ODB — довольно жирный фреймворк на эту тему. _>>2. SOCI — лёгкая библиотечка (мой выбор до появления sqlpp11, т.к. я не люблю жирные фреймворки). S>Так и приводи примеры из них. Я тебе кучу ссылок и примеров привожу. Просто понятно, что ты ими не пользуешься.
Какие примеры и для чего? ) Ты сформулируй точно тезис, который пытаешься доказать. Желательно с аргументами. Я на него посмотрю и выскажу своё согласие/несогласие. Тоже с аргументами. А пока я не пойму о чём у нас собственно основной спор и для чего ты выкладываешь какие-то куски кода.
_>>Это похоже как раз ты имел дело исключительно с EF и меряешь по нему весь остальной мир. ))) Я же имел дело с ORM в разных языках, в том числе и в динамических (где с этим всё гораздо проще и сильнее). И там популярны совсем другие практики (хотя очевидно, что сделать аналогичное решение тривиально). S> Я исключительно имею дело с 1С. EF это хобби. И я вижу огромные плюсы.
Ну вот тогда советую посмотреть (в рамках хобби) на другие решения, чтобы иметь представление о возможных вариантах. Скажем какой-нибудь SQLAlchemy для начала глянуть.
_>>Ну так всё в точности как я и говорил. ObservableCollection, реализующая биндинг, не имеет никакого отношения к EF. Или может тебе показалось, что я говорил что биндинга нет во всём .net? ))) S> Ну вообще то это есть реализация классов и прокси которая реализуется компилятором и которые являются сущностями EF.
ObservableCollection не генерируется компилятором, а лежит в System.dll. И да, в EF создаются всякие там промежуточные классы для работы с БД (на то оно и ORM), но к биндингу с GUI это отношения не имеет.
Здравствуйте, Ikemefula, Вы писали:
I>>>Испокон веков писали на С++, даже ОС реального времени наклепали десятками для таких случаев. I>·>Испоконнее — pure C или даже ассемблер. Но традиция — не аргумент. I>Ассемблер — очень смешно.
На спец-железе — не очень.
I>·>Нет гарантии и в случае с умными указателями, что освобождение заковыристого графа не нарвётся на lock или тупо будет работать долго, например, удаление одного объекта вызвало разрушение целой толпы других, gc же может съесть слона по кусочкам. А вообще есть Zing JVM и прочие RT GC. Задежка GC более 10ms — репортим баг. I>Умный указатель это решается легко и руками.
Как? Как контролировать, что smartPtr.release() сожрёт не более N микросекунд?
I>lock — в low latency никто такое не имплементит изначально I>"удаление одного объекта вызвало разрушение целой толпы других" - I> а 1 в 1 как в джаве, только проблемы переносятся на GC
Да, но gc не обязан это делать всё и сразу, вместо паузы в 100ms он сделает 1500 пауз по 100us. Да, throughput может и меньше, зато latency предсказуемее.
Можно, конечно, такое же соорудить и в C++, но это будет закат солнца вручную.
I> б 1 в 1 как в джаве, если разрушение это не просто занулени, а еще небольшая логика I> в если убрать сматрпоинтеры, что часто даже лучше чем в джаве I>Итого — на плюсах как минимум не хуже
Да, очевидно. Ибо сама java на C++ написана.
I>GC ты вообще не контролируешь, никак и гарантии у тебя сильно хилые.
GC это те же смартпоинтеры по сути, но более строгие, а значит контроля больше.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, alex_public, Вы писали:
_>·>Это не частный случай, а наиболее простая имплементация. Конечно, можно внимательно изучить, установить время жизни каждого объектика, но это сложно контролировать и тестировать, а в случае ошибки — undefined behaviour. В случае же java — самое страшное что будет — это latency spike из-за garbage collection, а не порча данных, как в случае ошибок с указателями. _>Ничего подобного. Ты путаешь время жизни объектов и время жизни потоков. Вот смотри, допустим у нас есть главный поток (не обязательно по приложению, а скажем по задачке некой), который порождает N других потоков, с которыми взаимодействует через общую память (не факт что лучшее решение, но раз ты его хочешь, то давай обсудим). Для этого достаточно выделить память в главном потоке и хранить её как unique_ptr (или вообще просто объявить локальную переменную, что заметно удобнее). А дочерним потокам передать голый указатель (или вообще ссылку, что заметно удобнее) на эти данные. Такая система будет 100% безопасна в случае гарантий завершения дочерних потоков раньше главного. Если подобные гарантии не следуют из логики задачи, то их можно легко получить ручным способом, разместив в конце главного потока код ожидания (банальный thread.join() в случае C++) завершения дочерних потоков.
thread.join — опять локи. Да и жизнь потоков тут не причём.
Собственно об этом я и говорю "100% безопасна в случае" vs "100% безопасна".
_>Так что, как видишь, у нас нет никаких намёков на необходимость использования shared_ptr для реализации взаимодействия потоков через общую память.
Если надо "100% безопасна", то никуда не денешься.
_>·>Модель акторов — в первую очередь для упрощения параллелизма, а не low latency. _>Всё правильно, упрощение. Которое при этом обеспечивает ещё и гарантию безопасности (которую в случае модели общей памяти надо достигать локами, в любом языке программирования) взаимодействия потоков. Ну а при правильной реализации можно получить ещё и быстродействие не хуже модели общей памяти.
Да не надо локи. Есть много других механизмов.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, T4r4sB, Вы писали:
TB>·>А как узнать-то? Особенно в случае сложной системы, код которой постоянно меняется толпой программистов? TB>В случае бардака — никак.
Почему никак? В случае java всегда так.
TB>·>Я имею в виду, что "сигнал" это тоже нечто передаваемое между тредами — и тоже не даётся бесплатно и обычно содержит локи внутри. TB>Сигнал о конце работы вряд ли создаст проблему производительности.
Если не создаст — повезло с задачей. В low latency — любой lock создаёт проблемы.
TB>·>Зачем же локи-то... Есть же volatile, happens-before, atomic и прочие вкусности. TB>·>Да и, скажем, в жабе-шарпе есть иммутабельные классы, которые безопасно использовать всегда без всяких оговорок. В C++ они принципиально невозможны из-за наличия деструктора, не говоря уж о const_cast и почри памяти. TB>Если уж говорить про const_cast, то я могу сказать, что в жабе можно сделать так, что 2*2=5. Это тоже правда, и это тоже наброс.
Эээ. Давай, сделай. Интересно как можно похакать верифицируемый байт-код.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
_>>Ничего подобного. Ты путаешь время жизни объектов и время жизни потоков. Вот смотри, допустим у нас есть главный поток (не обязательно по приложению, а скажем по задачке некой), который порождает N других потоков, с которыми взаимодействует через общую память (не факт что лучшее решение, но раз ты его хочешь, то давай обсудим). Для этого достаточно выделить память в главном потоке и хранить её как unique_ptr (или вообще просто объявить локальную переменную, что заметно удобнее). А дочерним потокам передать голый указатель (или вообще ссылку, что заметно удобнее) на эти данные. Такая система будет 100% безопасна в случае гарантий завершения дочерних потоков раньше главного. Если подобные гарантии не следуют из логики задачи, то их можно легко получить ручным способом, разместив в конце главного потока код ожидания (банальный thread.join() в случае C++) завершения дочерних потоков. ·>thread.join — опять локи. Да и жизнь потоков тут не причём. ·>Собственно об этом я и говорю "100% безопасна в случае" vs "100% безопасна".
Лок перед завершение потока никого не беспокоит, т.к. это по сути просто отложенное освобождение ресурсов — никаких данных уже никто не ожидает.
_>>Так что, как видишь, у нас нет никаких намёков на необходимость использования shared_ptr для реализации взаимодействия потоков через общую память. ·>Если надо "100% безопасна", то никуда не денешься.
Ну ОК, раз ты так считаешь, то тогда приведи пример взаимодействия потоков в котором на твой взгляд невозможно обойтись без shared_ptr.
_>>·>Модель акторов — в первую очередь для упрощения параллелизма, а не low latency. _>>Всё правильно, упрощение. Которое при этом обеспечивает ещё и гарантию безопасности (которую в случае модели общей памяти надо достигать локами, в любом языке программирования) взаимодействия потоков. Ну а при правильной реализации можно получить ещё и быстродействие не хуже модели общей памяти. ·>Да не надо локи. Есть много других механизмов.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Serginio1, Вы писали:
_>>>Эту библиотеку мало используют, потому что она только недавно появилась на свет. Если тебя интересуют популярные и проверенные временем ORM решения на C++ то смотри: _>>>1. ODB — довольно жирный фреймворк на эту тему. _>>>2. SOCI — лёгкая библиотечка (мой выбор до появления sqlpp11, т.к. я не люблю жирные фреймворки). S>>Так и приводи примеры из них. Я тебе кучу ссылок и примеров привожу. Просто понятно, что ты ими не пользуешься.
_>Какие примеры и для чего? ) Ты сформулируй точно тезис, который пытаешься доказать. Желательно с аргументами. Я на него посмотрю и выскажу своё согласие/несогласие. Тоже с аргументами. А пока я не пойму о чём у нас собственно основной спор и для чего ты выкладываешь какие-то куски кода.
Я привожу то, что хочу видеть в тех библиотеках, которые как ты считаешь круче EF
_>>>Это похоже как раз ты имел дело исключительно с EF и меряешь по нему весь остальной мир. ))) Я же имел дело с ORM в разных языках, в том числе и в динамических (где с этим всё гораздо проще и сильнее). И там популярны совсем другие практики (хотя очевидно, что сделать аналогичное решение тривиально). S>> Я исключительно имею дело с 1С. EF это хобби. И я вижу огромные плюсы.
_>Ну вот тогда советую посмотреть (в рамках хобби) на другие решения, чтобы иметь представление о возможных вариантах. Скажем какой-нибудь SQLAlchemy для начала глянуть.
Ты взял на себя утверждение, что EF отстой. Тебе и доказывать. Я привожу тебе решения которые есть в EF.
_>>>Ну так всё в точности как я и говорил. ObservableCollection, реализующая биндинг, не имеет никакого отношения к EF. Или может тебе показалось, что я говорил что биндинга нет во всём .net? ))) S>> Ну вообще то это есть реализация классов и прокси которая реализуется компилятором и которые являются сущностями EF.
_>ObservableCollection не генерируется компилятором, а лежит в System.dll. И да, в EF создаются всякие там промежуточные классы для работы с БД (на то оно и ORM), но к биндингу с GUI это отношения не имеет.
Кончно, оно есть у DBSEt.Local https://msdn.microsoft.com/ru-ru/library/gg696248(v=vs.113).aspx
Пространство имен: System.Data.Entity
Сборка: EntityFramework (в EntityFramework.dll)
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, ·, Вы писали:
·>Почему никак? В случае java всегда так.
Да, жаба лучше себя ведёт, когда надо нанять 100500 индусов, это её известно преимущество.
·>Если не создаст — повезло с задачей. В low latency — любой lock создаёт проблемы.
Сборка мусора — это тоже лок.
·>Эээ. Давай, сделай. Интересно как можно похакать верифицируемый байт-код. http://ideone.com/o1h0hR
const_cast ничем не лучше этого кода.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, ·, Вы писали:
I>>GC ты вообще не контролируешь, никак и гарантии у тебя сильно хилые. ·>GC это те же смартпоинтеры по сути, но более строгие, а значит контроля больше.
GC это тяжелый алгоритм, который работает в фоне, ты максимум можешь выключить его или включить, конфигурацию задать на старте и всё.
Смартпоинтеры можно например переписать и отказаться от счетчиков ссылок, заюзать любую из сотен возможностей по управлению ресурсами и тд и тд и тд.
На худой конец, "писать как на Си"
С с GC у тебя будет всегда GC и никуда от этого не денешься. Любое твое телодвижение должно быть согласовано с GC, иначе будут вылазить задержки.
Ошибся "здесь" — задержка вылезет черз секунду "там"
Здравствуйте, ·, Вы писали:
dot>Это не частный случай, а наиболее простая имплементация. Конечно, можно внимательно изучить, установить время жизни каждого объектика, но это сложно контролировать и тестировать, а в случае ошибки — undefined behaviour. В случае же java — самое страшное что будет — это latency spike из-за garbage collection, а не порча данных, как в случае ошибок с указателями.
При использовании Java в таких случаях отказываются и от GC и от классов, и нарезают вручную массивы байт на структуры. Получить порчу данных в таком случае на порядки проще чем на высокоуровневом C++.
Вот конкретный пример (первые минут двадцать) http://www.youtube.com/watch?v=Q-7y1u9kZV0
Здравствуйте, ·, Вы писали:
dot>Да, но gc не обязан это делать всё и сразу, вместо паузы в 100ms он сделает 1500 пауз по 100us. Да, throughput может и меньше, зато latency предсказуемее.
Если ограничивать GC пороговой latency — то можно получить OOM — банально скорость очистки будет меньше необходимой.
При этом учти что полноценный цикл GC линеен от количества N живых объектов — может быть например большое N, при малом потоке изменений reachable/unreachable.
dot>Можно, конечно, такое же соорудить и в C++, но это будет закат солнца вручную.
Почему вручную-то? Если есть такой развесистый граф владения — то и очищай его по частям, автоматически.
Да и возникают они в Java на порядки чаще чем в C++. Элементарный пример: массив объектов, агрегирующих другие объекты, агрегирующих другие ... — вполне типичная ситуация. На Java будет тот самый развесистый граф, а на C++ может быть просто по сути один вектор освобождающийся за O(1) — так как value semantics.
Здравствуйте, Ikemefula, Вы писали:
I>GC это тяжелый алгоритм, который работает в фоне, ты максимум можешь выключить его или включить, конфигурацию задать на старте и всё. I>Смартпоинтеры можно например переписать и отказаться от счетчиков ссылок, заюзать любую из сотен возможностей по управлению ресурсами и тд и тд и тд. I>На худой конец, "писать как на Си"
"писать как на Си (для производительности)" — распространённый миф/байка. Отказавшись от C++ в пользу "как на C" — ты не получишь никаких преимуществ относительно производительности, а вот недостатки вполне. Точнее есть пара тонких абстрактных моментов, но речь точно не о них.
И, например, там где нужен ref-counting в C++ — он нужен и в C http://rsdn.ru/forum/philosophy/6200891.1
Здравствуйте, alex_public, Вы писали:
_>·>thread.join — опять локи. Да и жизнь потоков тут не причём. _>·>Собственно об этом я и говорю "100% безопасна в случае" vs "100% безопасна". _>Лок перед завершение потока никого не беспокоит, т.к. это по сути просто отложенное освобождение ресурсов — никаких данных уже никто не ожидает.
Тут ведь как... Поток можно и не завершать, или приступить к обработке следующего действия.
_>>>Так что, как видишь, у нас нет никаких намёков на необходимость использования shared_ptr для реализации взаимодействия потоков через общую память. _>·>Если надо "100% безопасна", то никуда не денешься. _>Ну ОК, раз ты так считаешь, то тогда приведи пример взаимодействия потоков в котором на твой взгляд невозможно обойтись без shared_ptr.
Если тебе нужно чтобы не было обращений по невалидным указателям, то ты не можешь делать предположение, что объект по голому указателю ещё жив — надо использовать smart pointers.
_>>>·>Модель акторов — в первую очередь для упрощения параллелизма, а не low latency. _>>>Всё правильно, упрощение. Которое при этом обеспечивает ещё и гарантию безопасности (которую в случае модели общей памяти надо достигать локами, в любом языке программирования) взаимодействия потоков. Ну а при правильной реализации можно получить ещё и быстродействие не хуже модели общей памяти. _>·>Да не надо локи. Есть много других механизмов. _>Например? )
CAS, volatile, happens-before.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
_>>>>Так что, как видишь, у нас нет никаких намёков на необходимость использования shared_ptr для реализации взаимодействия потоков через общую память. _>>·>Если надо "100% безопасна", то никуда не денешься. _>>Ну ОК, раз ты так считаешь, то тогда приведи пример взаимодействия потоков в котором на твой взгляд невозможно обойтись без shared_ptr. dot>Если тебе нужно чтобы не было обращений по невалидным указателям, то ты не можешь делать предположение, что объект по голому указателю ещё жив — надо использовать smart pointers.
Этот use-case формулируется немного по-другому, например: нужно чтобы ресурс освобождался как только завершится последний поток его использующий, и какой из них будет последним — заранее не известно.
Вот так — да, как вариант решения подсчёт ссылок, и то в малом количестве мест. Только решать эту проблему нужно и в C, и сюрприз в Java. На Java кстати какое решение можешь предложить?
_>>>>·>Модель акторов — в первую очередь для упрощения параллелизма, а не low latency. _>>>>Всё правильно, упрощение. Которое при этом обеспечивает ещё и гарантию безопасности (которую в случае модели общей памяти надо достигать локами, в любом языке программирования) взаимодействия потоков. Ну а при правильной реализации можно получить ещё и быстродействие не хуже модели общей памяти. _>>·>Да не надо локи. Есть много других механизмов. _>>Например? ) dot>CAS, volatile, happens-before.
На них точно также получаются локи. Чтобы их не было, нужно использовать например lock-free / wait-free схемы.
Здравствуйте, ·, Вы писали:
TB>>А вот при одновременном обращении к содержимому указателя — возможно, локи нужны, как и в жабе и в шарпе. dot>Зачем же локи-то... Есть же volatile, happens-before, atomic и прочие вкусности.
Это лишь средства, с помощью которых в том числе получаются локи
dot>Да и, скажем, в жабе-шарпе есть иммутабельные классы, которые безопасно использовать всегда без всяких оговорок. В C++ они принципиально невозможны из-за наличия деструктора,
Причём тут деструктор? Он относится к времени жизни, а не к иммутабельности/константности. Когда деструктор начал работу — время жизни объекта уже закончилось, если к нему кто-то обратился после этого извне — то будут проблемы, независимо от того была ли константность или нет.
dot>не говоря уж о const_cast
Не, не серьёзно.
dot>и почри памяти.
В любой непонятной ситуации приводи как аргумент возможную порчу памяти