Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
«Ссылка должна оставаться залоченной пока есть вероятность что объект будет использован»
unref(ptr);
ptr = NULL;
потому что именно в многопоточной среде проблема одновременного общего доступа к данным наиболее актуальна.
Хэндл решает проблему передачи объекта между потоками в том плане, что передав в поток хэндл мы всегда можем попробовать залочить объект и убедиться в том что он жив, или же понять, что объект уже умер не создавая опасных ситуаций
Минус в том что мы не можем произвольно освобождать объект на время а потом пытаться залочить вновь, если он временно не требуется.
Проблема общего доступа к данным решается с помощью примитивов синхронизации (мютексов, например).
Вам надо или залочить его в первом треде или с вероятностью 50% вы получите null во втором треде. Конечно, опасной ситуации это не создаст, но и объекта вы не получите. Толку от такой надежности?
Хм, а как это «временно не требуется»?
Я с удовольствием прочитаю если вы расскажете как решить описанную мной проблему с помощью примитивов синхронизации.
Рассмотренная ситуация является утрированной, разумеется никто и никогда так не делает.
Ну например объект требуется только во время каких-то операций, занимающих конечное время (чтение из сокета при наличии данных, к примеру). В остальных случаях доступ к объекту не требуется.
Тем не менее в этой ситуации у handle нет никаких преимуществ перед обычным встроенным счётчиком ссылок. И там и там надо делать ref() в вызывающем потоке. Поэтому я не понимаю, зачем вы приводили этот пример.
Потому что вы путаете понятие общего доступа и общего владения.
Вы предлагаете использовать ваш handle именно в режиме weak refference, т.е. отпускать ссылку сразу после использования и потом молиться, что кто-то ещё держит этот сокет, что бы вы могли взять ссылку ещё раз.
В данной ситуации (в первой, там где ошибка) у handle есть одно огромное преимущество: он не вызовет ошибок обращения к памяти.
В данном случае рассматривается общий доступ к памяти
В моей практике есть десятки случаев когда нужен именно weak reference.
Например, предложите мне другой способ избежать циркулярных зависимостей.
Ну да, циклические зависимости — это как раз то место где и нужен weak ptr. Общий на всю систему сокет — это не то место, где нужен weak ptr.
Правильное использование handle не вызовет ошибки обращения к памяти.
Правильное использование тупого счетчика ссылок тоже не вызовет ошибок обращения к памяти.
Извините, но в данном случае не рассматривается общий доступ к памяти.
Но случаев когда нужна именно strong refference всё же больше, разве нет?
Если вы забыли проверить на NULL в бэктрейсе дампа вы это сразу увидите.
Гарантия безошибочности чтения и записи в выделенный кусок памяти — это не доступ?
Проблема ABA с хэндлами — это не доступ?
Давайте не заниматься придирками и безудержным критиканством.
Как правило один объект или трэд порождает объект, он им и владеет и занимается.
это… ну даже не знаю что это.
но ваша постановка задачи неверна. И поэтому вы сделали неверные выводы в конце статьи
Ну вот это как раз одно из важнейших условий консистентности объекта.
А что конкретно вам не понравилось в постановке задачи?
И что показалось неверным в выводах, которые, я считаю, довольно очевидны?
Ну в некотором смысле да. Но это всё зависит от среды. Например в java или .net в принципе не может возникнуть этой проблемы.
Я понимаю, что хендлы помогли решить какую-то вашу проблему с многопочностью.
Как вы планируете бороться с переполнением версии?
В данном случае нет никакой разницы между однопоточной и многопоточной средой. Собственно проблема совместного владения объектами (а вы решаете именно её) довольно таки ортогональна многопоточности. По большему счету, для поддержки многопоточности надо просто решить проблему атомарности счётчика ссылок.
Просто как я говорил понятие владения довольно ортогонально к многопоточности.
кроме «атомарного» volatile и одного натянутого примера
на самом деле. Вам ещё нужен мютекс на пул
Что в статье есть такого (кроме «атомарного» volatile и одного натянутого примера), что имеет какое-либо отношение к многопоточности?
В однопоточном приложении счётчика ссылок более чем достаточно для определения времени жизни объекта. И хэндлы в однопоточном приложении не нужны.
Мммм, какое преимущество хэндлы имеют именно в многопоточных приложениях? Я прочитал вашу статью, комментарии, но так и не понял.
Вы о том примере с передачей объекта между потоками? Не покажете пример кода как гарантировано передать объект между двумя потоками с использованием хендлов? При условии, что в вызывающем потоке этот объект больше не нужен?
Использование handle и intrusive reference counter-ов в многопоточных средах в языке C