Доступ к shared_ptr через локальное хранилище потока - PullRequest
1 голос
/ 14 февраля 2012

У меня есть коллекция такой информации:

std::list< boost::shared_ptr<DataEntry> > m_Entries;

Доступ к списку осуществляется несколькими потоками. Большую часть времени список только для чтения, но иногда поток должен будет добавить или удалить записи из списка. Таким образом, сам список защищен блокировкой чтения / записи, но записи не защищены.

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

Характер доступа таков, что данный поток обычно будет обращаться к одной конкретной записи несколько раз, а иногда и к другой (изменяющейся) записи. Не имеет значения, устарели ли данные, если они не удаляются во время использования. В настоящее время каждый раз, когда ему нужна запись, он должен получить блокировку, выполнить поиск в списке, скопировать shared_ptr, а затем снять блокировку. Нигде поток не может хранить указатель между доступами; он должен каждый раз отпускать и восстанавливать.

Как таковой, я думаю, что может быть выигрыш в производительности от кэширования наиболее часто используемой записи (как shared_ptr или weak_ptr) в локальном хранилище потока, чтобы избежать необходимости вообще блокировать блокировку в большинстве общий случай.

К сожалению, я использую VS2008, и его __declspec(thread) не поддерживает типы не POD, такие как умные указатели. Я не могу сохранить пустой указатель, так как это не обеспечит гарантии отсутствия удаления, которые мне нужны. Я полагаю, что мог бы сохранить weak_ptr*, но это привело бы к утечке памяти (и слабому количеству ссылок) при выходе из потока (хотя у меня есть ловушка, которая вызывается при "нормальном" выходе из потока, так что это может быть немного смягчено) , И, по понятным причинам, хранение shared_ptr* будет еще хуже.

Учитывая сложность и то, что блокировки обычно не требуются, я не уверен, что возможное предельное повышение производительности стоит хлопот. Но мне было интересно, если я пропускаю лучший способ сделать это. (И мне также любопытно, если что-то улучшится в C ++ 11, поскольку в нем улучшена поддержка потоков.)

1 Ответ

0 голосов
/ 14 февраля 2012

Попробуйте Boost's Thread Local Storage - Я настроен оптимистично, что он может работать с вашим компилятором VS 2008.

...