
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
Страницы: (56) « Первая ... 33 34 [35] 36 37 ... 55 56 ( Перейти к последнему сообщению ) |
![]() |
Сообщ.
#511
,
|
|
Цитата applegame @ Ну а указатель на иммутабельные данные разве не есть исключительно малая порция сообщений, которые можно тупо копировать и не париться ни над счётчиком ссылок, ни над потокобезопасностью? Нет, указатель может стать невалидным, если поток-владелец вызвал деструктор объекта, пока поток, получивший от него указатель на данные, ещё не завершился. Впрочем, с передачей функции может возникнуть та же фигня, если она создаёт отдельный поток. В общем, поток-владелец не должен возвращать "сырой" объект-срез, имеющий указатель на исходный массив, а лишь предоставлять небольшой, копируемый кусок по запросу. 1) При этом, поток-владелец, например, создаёт канал для взаимодействия с потребителем (передачи ему копируемого элемента массива) и, храня ссылку на канал, уведомляет его о своём уничтожении в своём деструкторе. 2) Владельцем же канала является поток-потребитель, который автоматически уничтожит канал при своей смерти. Канал, в свою очередь, в деструкторе, уведомляет поток-владелец, если тот не умер сам, (о чём канал знает из предыдущего пункта), который его (канал) создал, чтобы тот убрал его из списка живых каналов. При чём, уже сам канал может отдавать потребителю сырой указатель на объект, скопированный в его буфер, ведь канал (и соответственно этот объект) будут жить не больше, чем поток-потребитель. Ну, я не очень знаком с C++/потоками и всем таким прочем, поэтому, возможно, фигню написал, и, наверняка, тут есть проблемы, но как бы вот. Копирование только по мере необходимости и проблем с памятью, вроде, нет. BTW, на сколько я читал, в Erlang'е всё тупо копируется, например. Добавлено Вообще, развивая мысль: передавай между потоками не указатели на сами объекты, а unique_ptr на сообщения. Ведь отправителю сообщение нужно только до момента отправки, а получателю только с момента получения, т.е. в каждый промежуток времени у сообщения только один владелец, соответственно никакие shared_ptr и подсчёт ссылок не нужны совсем. Ты можешь спросить: это что мне, создавать кучу объектов-сообщений? Ну так с иммутабельными объектами тебе _придётся_ создавать кучу объектов в любом случае. Кроме того, если ты вдруг захочешь изменить интерфейс объекта-ресурса, поток-потребитель может этого не понять, а при использовании объектов-сообщений, их, скорее всего придётся менять меньше, т.к. сообщения во многих случаях смогут инкапсулировать работу с новым интерфейсом, не затрагивая потребителей. Плюс, сообщения будет проще сериализовать и разделить потребителей и владельца по разным процессорам/машинам. |
Сообщ.
#512
,
|
|
|
Во-первых на одну синхронизацию массива приходится сотня копирований shared_ptr. Во-вторых я тебе уже объяснял, о чем я на самом деле беспокоюсь. Сочинять-то зачем, тролль несчастный.
![]() Ну что ты такой бестолковый? Очевидно же чего - безопасность космических полетов. Цитата D_KEY @ Я так говорю, потому что сущность shared_ptr<T> объективно сложнее сущности T*. И причем здесь сложность GC? И о каких возможных случаях утечек ты говоришь?Ты так говоришь, как будто "простое" и "сложное" - это объективные вещи ![]() Я вот не помню, чтобы shared_ptr мне когда-либо казался сложным. GC сам по себе гораздо сложнее, как и возможные случаи утечек при его использовании. Цитата Qraizer @ Где именно?Мне кажется, applegame, ты смешал иммутабельность данных, подлежащих обработке, с иммутабельностью контейнера, их содержащего. Цитата korvin @ Такого не произойдет если есть GC, потока-владельца не существует. объектами владеет GC, который уничтожит их, как только перестанут существовать указатели на объекты во всех потоках приложения. Все потоки использующие объект отработали, этот же объект удален из массива - GC его удаляет.Весьма похоже на shared_ptr, только без всякого shared_ptr.Нет, указатель может стать невалидным, если поток-владелец вызвал деструктор объекта, пока поток, получивший от него указатель на данные, ещё не завершился. Цитата korvin @ Это ортогонально обсуждаемому вопросу. Я и так применяю сообщения там где это имеет смысл. Речь идет о совместном доступе нескольких потоков к одним и тем же данным. Вообще, развивая мысль: передавай между потоками не указатели на сами объекты, а unique_ptr на сообщения. Ведь отправителю сообщение нужно только до момента отправки, а получателю только с момента получения, т.е. в каждый промежуток времени у сообщения только один владелец, соответственно никакие shared_ptr и подсчёт ссылок не нужны совсем. |
Сообщ.
#513
,
|
|
|
Цитата applegame @ Во-первых на одну синхронизацию массива приходится сотня копирований shared_ptr. И вот снова появились новые условия в задаче ![]() Цитата Ну что ты такой бестолковый? Очевидно же чего - безопасность космических полетов. А если серьезно? У тебя "безопасность" какое-то магическое слово. Цитата Я так говорю, потому что сущность shared_ptr<T> объективно сложнее сущности T*. Вот никогда не понимал этого. Ты же не просто используешь T*, ты используешь T* + GC. А эта система сложнее shared_ptr. Цитата И причем здесь сложность GC? И о каких возможных случаях утечек ты говоришь? Все те, для которых предназначены SoftReference и WeakReference в той же Java. Даже с GC ты не можешь просто забить на работу с памятью и анализ времени жизни объектов. Пусть и в более редких случаях, но зато менее явных. Цитата Я и так применяю сообщения там где это имеет смысл. Речь идет о совместном доступе нескольких потоков к одним и тем же данным. Не знаю, по мне так ты хочешь странного. |
Сообщ.
#514
,
|
|
|
Цитата D_KEY @ Они не новые:И вот снова появились новые условия в задаче ![]() Цитата applegame @ Ну смотри сам. У меня есть достаточно большое количество (сотни тысяч) относительно небольших объектов. Эти объекты хрянятся в некой структуре, что-то вроде весьма узкоспециализированной простой БД в памяти. Также есть множество потоков, которые работают с какими-то срезами из этой БД, обычно lazy-range/слайсы, иногда небольшие иммутабельные масивы по нескольку десятков объектов. Разговор с тобой стал неприятным для меня. Ты как обычно скатился в жЫрноту: начал "забывать", то что говорилось раньше и придумывать то, чего не говорилось, делать вид, что не понимаешь о чем речь, спрашивать значение общеизвестных терминов, требовать формализовать неформализуемое, выводить диалог на обсуждение малозначительных сущностей и так далее. Я не хочу по-кругу повторять одно и тоже. Посему предлагаю поменяться ролями. ![]() Цитата D_KEY @ Что ты имеешь в виду? Почему это она сложнее? Вот никогда не понимал этого. Ты же не просто используешь T*, ты используешь T* + GC. А эта система сложнее shared_ptr. ![]() Цитата D_KEY @ А для чего предназначены в Java SoftReference и WeakReference? И ты так говоришь, как будто "явность" - объективный критерий. Все те, для которых предназначены SoftReference и WeakReference в той же Java. Даже с GC ты не можешь просто забить на работу с памятью и анализ времени жизни объектов. Пусть и в более редких случаях, но зато менее явных. ![]() Цитата D_KEY @ А по мне ты просто не сталкивался со сколь-нибудь сложными многопоточными приложениями. Не знаю, по мне так ты хочешь странного. |
Сообщ.
#515
,
|
|
|
Цитата applegame @ Они не новые И где тут сказано, что лочишь мьютексом ты сразу для работы со многими элементами? Цитата Цитата D_KEY @ Что ты имеешь в виду? Почему это она сложнее? Вот никогда не понимал этого. Ты же не просто используешь T*, ты используешь T* + GC. А эта система сложнее shared_ptr. ![]() Я имею в виду, что shared_ptr - это подсчет ссылок на объект, его работа детерминирована и прозрачна. GC бывают очень разные, с разными стратегиями обхода, распределения памяти, работы с поколениями(и обработки ссылок между поколениями), гарантий времени остановки и пр. и пр. Цитата А для чего предназначены в Java SoftReference и WeakReference? Для того, чтобы с разной степенью свободы позволять GC удалять те объекты, на которые мы еще имеем ссылки. Цитата И ты так говоришь, как будто "явность" - объективный критерий. ![]() В случае ручного управления памятью утечки связаны с ошибками программиста, есть специальные тулзы, которые ищут утечки и пр. В случае RC есть детекторы циклов, которые покажут наличие циклических ссылок. Случаи "случайных" ссылок тяжелее выявлять и автоматических инструментов я не видел. Если есть - расскажи ![]() Цитата А по мне ты просто не сталкивался со сколь-нибудь сложными многопоточными приложениями. ![]() Добавлено И да, все хочу спросить, ты профайлером в том или ином виде пользуешься или на глаз оцениваешь, что медленно? |
Сообщ.
#516
,
|
|
|
Цитата D_KEY @ Какое дело программисту до всей этой внутренней кухни? Убрал последнюю ссылку и забыл про объект и нет сюрпризов с неожиданным обращением к уже удаленному объекту. То же самое можно было бы сказать и о shared_ptr, если бы не несколько подводных камней и ограничений использования.Я имею в виду, что shared_ptr - это подсчет ссылок на объект, его работа детерминирована и прозрачна. GC бывают очень разные, с разными стратегиями обхода, распределения памяти, работы с поколениями(и обработки ссылок между поколениями), гарантий времени остановки и пр. и пр. Цитата D_KEY @ Для того, чтобы с разной степенью свободы позволять GC удалять те объекты, на которые мы еще имеем ссылки. Цитата D_KEY @ А случаи "случайных" ссылок можно подумать не связаны с ошибками программиста В случае ручного управления памятью утечки связаны с ошибками программиста, есть специальные тулзы, которые ищут утечки и пр. В случае RC есть детекторы циклов, которые покажут наличие циклических ссылок. Случаи "случайных" ссылок тяжелее выявлять и автоматических инструментов я не видел. Если есть - расскажи ![]() ![]() ![]() Инструмент для обнаружения причины таких "утечек" не нужен. Потому что твои пресловутые "случайные" зависшие ссылки - явление весьма специфичное и точки их возникновения легко находимы без каких-либо инструментов, кроме собственной головы. Как правило, это кеши, которые забыли периодически очищать. Тут я тебе без всякого valgrind найду утечку. Цитата D_KEY @ Да, давай оставим. Но так как ты первый перешел на личности, то последнее слово за мной: ты - некомпетентен в этой области. ![]() По мне так все наоборот... Вернее, ты не умеешь такие приложения проектировать. Но давай оставим в покое личности и попытаемся поговорить конструктивно. ![]() |
Сообщ.
#517
,
|
|
|
Цитата applegame @ Но так как ты первый перешел на личности Нет ты ![]() Добавлено Цитата applegame @ Какое дело программисту до всей этой внутренней кухни? ![]() Добавлено Цитата applegame @ А случаи "случайных" ссылок можно подумать не связаны с ошибками программиста Это не ошибки. Это доверие сборщику. Но вернемся к конструктивному обсуждению. Мне так и неясна связь иммутабельности с наличием/отсутсвием GC. По-моему, все что ты говоришь справедливо и для мутабельных данных, разве нет? Твой ответ про профайлинг так же интересен. |
![]() |
Сообщ.
#518
,
|
|
Цитата applegame @ Вот тут я могу присоединиться к D_KEY-ю. Разве не ты начал говорить о неком контейнере для ссылок на иммутабельные объекты, который то и дело, что меняет своё состояние? Объясни мне, плз, как можно рассуждать о тем или иным способом поумневшим ссылках на иммутабельные объекты, напрочь игнорируя содержащий их контейнер? При том что если бы контейнер был константным, мы могли бы обойтись тупо сырыми поинтерами и не париться. Пока я не вижу, зачем бы вообще могло понадобиться отдаваемые объекты оборачивать в смарты. Цитата Qraizer @ Где именно?Мне кажется, applegame, ты смешал иммутабельность данных, подлежащих обработке, с иммутабельностью контейнера, их содержащего. Добавлено Цитата D_KEY @ Огласи уж полные условия, что ли. Без последующих отказов и дополнений. И вот снова появились новые условия в задаче |
Сообщ.
#519
,
|
|
|
Цитата Qraizer @ Ссылки из этого контейнера рассылаются другим потокам. Не весь контейнер, а его различные части.Объясни мне, плз, как можно рассуждать о тем или иным способом поумневшим ссылках на иммутабельные объекты, напрочь игнорируя содержащий их контейнер? Цитата D_KEY @ Это не ошибки. Это доверие сборщику. ![]() Но давайте вернемся к Цитата D_KEY @ к конструктивному обсуждению. Мне так и неясна связь иммутабельности с наличием/отсутсвием GC. По-моему, все что ты говоришь справедливо и для мутабельных данных, разве нет? В общем случае ты видимо прав. Прямой связи нет. Скаэем так, сочетание иммутабельности и GC дает нам дополнительные гарантии. Если функция в D получает иммутабельный объект, то у нас есть гарантия не только в том, что никто и никогда не изменит этого объекта, но и то что никто и никогда не удалит этот объект пока мы его используем. То есть эта функция получается более генерализованной. Совершенно все равно откуда и в каком окружении она будет вызвана. То есть immutable в GC-окружении получается как бы более полным что-ли. К сожалению у меня не получается формализовать свою мысль более точно. Как в C++ определить был ли объект изначально константным или нет? Насколько я знаю никак. Фактически immutable в D обозначает изначальную константность. При этом immutable неявно может быть скастовано в const, но не наоборот. Теперь вопрос: нужен ли immutable в C++? Добавлено Накопал интересную статью в википедии об иммутабельности: Persistent data structures. Эти структуры иммутабельны и их реализация требует наличия GC. И как я понимаю именно они используются в чисто функциональных языках вроде Хаскеля. |
Сообщ.
#520
,
|
|
|
Цитата applegame @ Ссылки из этого контейнера рассылаются другим потокам. Не весь контейнер, а его различные части. Т.е. мы имеем некоторый контейнер с данными, в который какие-то потоки кладут объекты, какие-то удаляют, а какие-то забирают элементы для того, чтобы их прочесть. Контейнер лочится мьютексом, а потоки работают сразу с группой объектов(иначе не имело бы смысл беспокоиться о копировании shared_ptr на фоне лока). Так? Цитата Такие же "утечки" можно получить и с shared_ptr и с голыми указателеми. В теории да, на практике вероятность ниже, поскольку и пользователи RC и пользователи ручного управления памятью сами обдумывают время жизни объектов, стратегию владения и пр. Цитата В общем случае ты видимо прав. Ок. А холивар GC vs не-GC не слишком интересная тема. ИМХО. Цитата Если функция в D получает иммутабельный объект, то у нас есть гарантия не только в том, что никто и никогда не изменит этого объекта, но и то что никто и никогда не удалит этот объект пока мы его используем. Гарантия того, что никто и никогда не удалит этот объект у нас есть в любом случае и никак с иммутабельностью не связана ![]() Цитата Эти структуры иммутабельны и их реализация требует наличия GC. Скажем так, они гораздо легче реализуются при наличии GC. |
![]() |
Сообщ.
#521
,
|
|
Цитата applegame @ И слава богу, что нет. Иначе от const не было бы никакого проку вообще, как сейчас от register. Или от C99-шного restrict. Зато есть (в какой-то мере) прямая противоположность: const volatile. И это ИМХО идеологически правильнее immutable. Как в C++ определить был ли объект изначально константным или нет? Насколько я знаю никак. Фактически immutable в D обозначает изначальную константность. При этом immutable неявно может быть скастовано в const, но не наоборот. Теперь вопрос: нужен ли immutable в C++? |
Сообщ.
#522
,
|
|
|
Цитата D_KEY @ Да. Похоже на текущую архитектуру, сильно правда упрощенно, но примерно так. Т.е. мы имеем некоторый контейнер с данными, в который какие-то потоки кладут объекты, какие-то удаляют, а какие-то забирают элементы для того, чтобы их прочесть. Контейнер лочится мьютексом, а потоки работают сразу с группой объектов(иначе не имело бы смысл беспокоиться о копировании shared_ptr на фоне лока). Так? |
![]() |
Сообщ.
#523
,
|
|
Цитата applegame @ Такого не произойдет если есть GC, потока-владельца не существует. объектами владеет GC, который уничтожит их, как только перестанут существовать указатели на объекты во всех потоках приложения. Все потоки использующие объект отработали, этот же объект удален из массива - GC его удаляет.Весьма похоже на shared_ptr, только без всякого shared_ptr. Спасибо, Кэп. А я-то думал, GC в лиспах, хаскеллах, джавах и прочих сишарпах --- это что-то другое. Цитата applegame @ Это ортогонально обсуждаемому вопросу. Я и так применяю сообщения там где это имеет смысл. Речь идет о совместном доступе нескольких потоков к одним и тем же данным. Всё просто: совместный доступ не нужен. Каждым ресурсом владеет только один поток. |
Сообщ.
#524
,
|
|
|
Цитата korvin @ Наверное думал, раз написал:Спасибо, Кэп. А я-то думал, GC в лиспах, хаскеллах, джавах и прочих сишарпах --- это что-то другое. Цитата korvin @ Нет, указатель может стать невалидным, если поток-владелец вызвал деструктор объекта, пока поток, получивший от него указатель на данные, ещё не завершился. Или решил, что речь идет о C++. Но тогда стоило бы написать, что ты говорил о другом языке, вместо благодарностей капитанам, нет? Цитата korvin @ А какая связть между владением ресурсом и совместным доступом к ресурсу? Всё просто: совместный доступ не нужен. Каждым ресурсом владеет только один поток. |
Сообщ.
#525
,
|
|
|
Цитата applegame @ Цитата D_KEY @ Да. Похоже на текущую архитектуру, сильно правда упрощенно, но примерно так.Т.е. мы имеем некоторый контейнер с данными, в который какие-то потоки кладут объекты, какие-то удаляют, а какие-то забирают элементы для того, чтобы их прочесть. Контейнер лочится мьютексом, а потоки работают сразу с группой объектов(иначе не имело бы смысл беспокоиться о копировании shared_ptr на фоне лока). Так? Можешь придумать похожую на твою, но более простую задачку, чтобы можно было поэкспериментировать? |