Повысьте общий указатель: одновременный доступ для чтения через несколько потоков

У меня есть поток, который выделяет память и присваивает ее общему указателю. Затем этот поток порождает 3 других потока X, Y и Z и передает копию общего указателя на каждого. Когда X, Y и Z выходят из объема, память освобождена. Но есть ли возможность, что 2 потока X, Y выходят из объема в том же самом моменте времени и существует состояние состязания на подсчете ссылок так вместо того, чтобы постепенно уменьшить его 2, это только постепенно уменьшается однажды. Так, теперь подсчет ссылок более новые спады 0, таким образом, существует утечка памяти. Обратите внимание, что, X, Y и Z только читают память. Пишущий или сбрасывая общий указатель. Короче говоря, состояние состязания на подсчете ссылок и это может там быть, может привести к утечкам памяти?

6
задан warren 20 April 2011 в 15:12
поделиться

5 ответов

Некоторые другие уже предоставили ссылки на документацию, объясняющую, что это безопасно.

Чтобы получить абсолютно неопровержимое доказательство, посмотрите, как Boost Smartptr фактически реализует свои собственные мьютексы с нуля в boost / smart_ptr / detail / sp_counted_base_gcc_x86.hpp (или в соответствующем файле вашей платформы).

2
ответ дан 8 December 2019 в 12:18
поделиться

Нет, согласно документации , эти проблемы не могут возникнуть:

Различные экземпляры shared_ptr могут быть «записаны» (доступны с помощью изменяемых операций, таких как operator = или reset ) одновременно несколькими потоками (, даже если эти экземпляры являются копиями и имеют один и тот же счетчик ссылок под .)

6
ответ дан 8 December 2019 в 12:18
поделиться

В документации говорится:

Различные экземпляры shared_ptr могут быть «записаны» (доступны с помощью изменяемых операций, таких как operator = или reset) одновременно несколькими потоками (даже если эти экземпляры являются копиями, и используют тот же счетчик ссылок внизу.)

Так что, если ни один из потоков не обращается к объектам указателей других потоков, все должно быть в порядке. Ознакомьтесь с примерами в документации и посмотрите, какой из них подходит для вашего случая.

1
ответ дан 8 December 2019 в 12:18
поделиться

boost :: shared_ptr использует блокировки (или атомарный доступ без блокировки), чтобы гарантировать, что счетчики ссылок обновляются атомарно (даже если это не очистить со страницы документации). Если вы пишете однопоточный код, вы можете настроить отказ от использования блокировок, определив макрос BOOST_SP_DISABLE_THREADS .

Обратите внимание, что примеры документации в http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/shared_ptr.htm # ThreadSafety , в котором обсуждаются проблемы с множественной записью из разных потоков, обсуждает эти потоки, действующие на одни и те же экземпляры shared_ptr (в примерах объекты shared_ptr могут быть глобальными), а не разные копии shared_ptr , которые указывают на один и тот же объект, что является обычным вариантом использования для shared_ptr . Пример, который вы даете в вопросе (действие на копии, указывающие на общий объект), является поточно-ориентированным.

12
ответ дан 8 December 2019 в 12:18
поделиться

Лучше всего перейти на TR1 или C ++ 0x shared_ptr, в отличие от разновидности Boost. Я считаю, что это стандартизовано, что они ДОЛЖНЫ быть потокобезопасными.

-2
ответ дан 8 December 2019 в 12:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: