Многопоточное чтение и запись в a :: stl :: vector, векторный ресурс трудно выпустить - PullRequest
3 голосов
/ 06 ноября 2008

Я пишу код в VS2005, используя его STL. У меня есть один поток пользовательского интерфейса для чтения вектора и рабочий поток для записи в вектор. Я использую :: boost :: shared_ptr как векторный элемент.

vector<shared_ptr<Class>> vec;

но я нахожу, если я манипулирую vec в обоих потоках в одно и то же время (я могу гарантировать, что они не посещают одну и ту же область, поток пользовательского интерфейса всегда читает область, содержащую информацию)

vec.clear (), кажется, не может освободить ресурс. проблема произошла в shared_ptr, он не может освободить свой ресурс.

В чем проблема? Это происходит потому, что, когда вектор достигает своего порядка, он перераспределяется в памяти, тогда исходная часть становится недействительной.

Насколько я знаю, при перераспределении итератор будет недействительным, поэтому некоторые проблемы также возникали, когда я использовал vec [i]. // -----------------------------------------------

Какие виды блокировки нужны? Я имею в виду: если элемент вектора является shared_ptr, когда поток A получает точку smart_p, другой поток B будет ждать, пока A не завершит операцию на smart_p, верно? Или просто добавьте блокировку, когда поток пытается прочитать точку, когда операция чтения завершена, поток B может продолжить что-то делать.

Ответы [ 3 ]

4 голосов
/ 06 ноября 2008

Когда вы обращаетесь к одному и тому же ресурсу из более чем одного потока, блокировка необходима. Если вы этого не сделаете, у вас есть все виды странного поведения, как вы видите.

Поскольку вы используете Boost, простой способ использовать блокировку - использовать библиотеку Boost.Thread. Лучшим видом блокировок, который вы можете использовать для этого сценария, являются блокировки чтения / записи; они называются shared_mutex в Boost.Thread.

Но да, то, что вы видите, по сути является неопределенным поведением из-за отсутствия синхронизации между потоками. Надеюсь, это поможет!

Изменить, чтобы ответить на второй вопрос OP: вы должны использовать блокировку чтения при чтении интеллектуального указателя из вектора и блокировку записи при записи или добавлении элемента в вектор (так, мьютекс только для вектора) , Если несколько потоков будут обращаться к объекту , на который указывает указатель (т. Е. На что указывает смарт-указатель), то для них должны быть установлены отдельные блокировки. В этом случае вам лучше поместить объект взаимного исключения в класс объекта.

0 голосов
/ 10 декабря 2008

Можно сделать одновременный доступ к списку или массиву, как это. Однако std :: vector не является хорошим выбором из-за его поведения при изменении размера. Чтобы сделать это правильно, нужен массив фиксированного размера или специальное поведение блокировки или обновления при изменении размера. Ему также нужны независимые передние и задние указатели снова с блокировкой или атомарным обновлением.

В другом ответе упоминаются очереди сообщений. Общий массив, как я описал, является распространенным и эффективным способом их реализации.

0 голосов
/ 07 ноября 2008

Другой альтернативой является полное устранение блокировки, обеспечивая доступ к вектору только в одном потоке. Например, имея рабочий поток, отправьте сообщение в основной поток с элементами для добавления в вектор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...