|
|
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
Обычно при синхронизации я использую критические секции для защиты переменных класса. Скажите, пожалуйста, для работы с контейнерами STL (map, vector) достаточно ли использования критической секции? Или использовать мьютексы? Один из поток обновляет данные в контейнеры map (добавляет или изменяет значения для данного ключа), другие потоки могут читать данные из контейнера? Честно говоря, не нашёл точных условия, которые делают итераторы контейнера недействительными? Может кто подскажет, какие проблемы могут быть при использовании контейнеров в многопоточных программах и в как избегать недействительности итераторов контейнера или подскажет ссылку на информацию по данному вопросу? Заранее спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 16:31 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
давай почитаем ман Vector reallocation occurs when a member function must increase the sequence contained in the vector object beyond its current storage capacity. Other insertions and erasures may alter various storage addresses within the sequence. In all such cases, iterators or references that point at altered portions of the sequence become invalid. If no reallocation happens, only iterators and references before the insertion/deletion point remain valid. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 17:11 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
так что синхронизируй доступ и будет тебе счастье ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 17:12 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
Так я и спрашиваю, каким образом в данном случае надо синхронизировать доступ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 17:15 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
Не будет счатья. Инвалидация итераторов совершенно не связана с многопоточностья (чти цитату) Инвалидироваться может любой итератор вектора или деки после опреации вставки или удаления, независимо от того много у тебя потов ил один. Просто итераторы не следует запоминать. И уже как следствие - не след итерироваться по контейнеру, в то время когда в него пытаются вставлять, удалять. Естественно не следует из двуж потоков модифицировать вектор. Можно и мьютексом защитить, но лучше блокировка чтение.запись ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 17:19 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
blindedНе будет счатья. Инвалидация итераторов совершенно не связана с многопоточностья (чти цитату) Инвалидироваться может любой итератор вектора или деки после опреации вставки или удаления, независимо от того много у тебя потов ил один. Просто итераторы не следует запоминать. И уже как следствие - не след итерироваться по контейнеру, в то время когда в него пытаются вставлять, удалять. Естественно не следует из двуж потоков модифицировать вектор. Можно и мьютексом защитить, но лучше блокировка чтение.запись но лучше блокировка чтение.запись - что вы здесь имеете в виду? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 17:24 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
OLEG_2005Так я и спрашиваю, каким образом в данном случае надо синхронизировать доступ? полностью синхронизировать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 17:26 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
пока итератор не изъюзаешь, критическую секцию не покидать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 17:28 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
Т.е. чтобы гаранитровать корректную работу нужно во время выполнения цикла запретить доступ дргугих потоков к контейнеру. Я использую контейнер map. CALCULATED_TI_DATA::iterator calculatedDataIterator; for (calculatedDataIterator = calculatedTiBuffer.begin(); calculatedDataIterator != calculatedTiBuffer.end(); calculatedDataIterator++) { Что-нибудь делаем с элементами контейнера } ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 17:28 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
OLEG_2005 blindedНе будет счатья. Инвалидация итераторов совершенно не связана с многопоточностья (чти цитату) Инвалидироваться может любой итератор вектора или деки после опреации вставки или удаления, независимо от того много у тебя потов ил один. Просто итераторы не следует запоминать. И уже как следствие - не след итерироваться по контейнеру, в то время когда в него пытаются вставлять, удалять. Естественно не следует из двуж потоков модифицировать вектор. Можно и мьютексом защитить, но лучше блокировка чтение.запись но лучше блокировка чтение.запись - что вы здесь имеете в виду? Посмотри например здесь ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 18:12 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
OLEG_2005 пишет: > Скажите, пожалуйста, для работы с контейнерами STL (map, vector) > достаточно ли использования критической секции? Да, достаточно. Или использовать > мьютексы? Или секции, или мьютексы. Мьютексы нужны только при межпроцессном взаимодействии, поэтому лучше секции. Один из поток обновляет данные в контейнеры map (добавляет или > изменяет значения для данного ключа), другие потоки могут читать данные > из контейнера? Нет. Весь доступ, как по чтению, так и по записи, должен быть защищен. Честно говоря, не нашёл точных условия, которые делают > итераторы контейнера недействительными? Прописаны и в стандарте, и в документации. Явно для каждой операции. Ищи лучше. Может кто подскажет, какие > проблемы могут быть при использовании контейнеров в многопоточных > программах Никаких не должно быть, только надо доступ к ним защищать. и в как избегать недействительности итераторов контейнера или > подскажет ссылку на информацию по данному вопросу? Заранее спасибо. При выполнении методов, инвалидирующих итераторы, надо заново инициализировать итераторы, и все. Это кстати написано хорошо у Меерса в Effective STL. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.05.2007, 19:11 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
MasterZiv OLEG_2005 пишет: > Скажите, пожалуйста, для работы с контейнерами STL (map, vector) > достаточно ли использования критической секции? Да, достаточно. Или использовать > мьютексы? Или секции, или мьютексы. Мьютексы нужны только при межпроцессном взаимодействии, поэтому лучше секции. Один из поток обновляет данные в контейнеры map (добавляет или > изменяет значения для данного ключа), другие потоки могут читать данные > из контейнера? Нет. Весь доступ, как по чтению, так и по записи, должен быть защищен. Честно говоря, не нашёл точных условия, которые делают > итераторы контейнера недействительными? Прописаны и в стандарте, и в документации. Явно для каждой операции. Ищи лучше. Может кто подскажет, какие > проблемы могут быть при использовании контейнеров в многопоточных > программах Никаких не должно быть, только надо доступ к ним защищать. и в как избегать недействительности итераторов контейнера или > подскажет ссылку на информацию по данному вопросу? Заранее спасибо. При выполнении методов, инвалидирующих итераторы, надо заново инициализировать итераторы, и все. Это кстати написано хорошо у Меерса в Effective STL. Posted via ActualForum NNTP Server 1.4 Большое спасибо за такой развёрнутый ответ. Но, всё равно остаётся вопрос. Если я ставлю критическую секцию в коде изменения контейнера и в коде обхода контейнера (а контейнер может сожержать достаточно много элементов и цикл быть длительным), то на врёмя обхода всего контейнера у меня блокируется доступ к элементам контейнера. Не приведёт ли это к снижению быстродействия? Хотя другого вариант, гарантируюшего коректную работу я не могу придумать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 09:24 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
> вопрос. Если я ставлю критическую секцию в коде изменения контейнера и в > коде обхода контейнера (а контейнер может сожержать достаточно много > элементов и цикл быть длительным), то на врёмя обхода всего контейнера у > меня блокируется доступ к элементам контейнера. Да, имено так. Не приведёт ли это к > снижению быстродействия? Может. Но делать нечего. Хотя другого вариант, гарантируюшего коректную > работу я не могу придумать. Его просто нет. Хотя можно цикл обработки написать так, чтобы он брал N-йый элемент из контейнера под мьютексом или секцией и затем освобождал контейнер. Это нужно наверное только если операции с элементами длинные. При этом сам элемент нужно скопировать из контейнера, поскольку после освобождения нет будет гарантии, что адрес этого объекта не поменяется всвязи с переаллокацией памяти или удалением элемента. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 10:53 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
MasterZiv Хотя можно цикл обработки написать так, чтобы он брал N-йый элемент из контейнера под мьютексом или секцией и затем освобождал контейнер. Это нужно наверное только если операции с элементами длинные. При этом сам элемент нужно скопировать из контейнера, поскольку после освобождения нет будет гарантии, что адрес этого объекта не поменяется всвязи с переаллокацией памяти или удалением элемента. Posted via ActualForum NNTP Server 1.4 Если я при переборе контейнера буду брать очередной элемент под мьютексом, то при переходе к следующему элементу нет гарантии правильности итератора (после особождения от мьютекса итератор может стать недействительным). Или я неправ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 11:26 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
OLEG_2005 Большое спасибо за такой развёрнутый ответ. Но, всё равно остаётся вопрос. Если я ставлю критическую секцию в коде изменения контейнера и в коде обхода контейнера (а контейнер может сожержать достаточно много элементов и цикл быть длительным), то на врёмя обхода всего контейнера у меня блокируется доступ к элементам контейнера. Не приведёт ли это к снижению быстродействия? Хотя другого вариант, гарантируюшего коректную работу я не могу придумать. Приведет, если контейнер нужно обрабатывать паралельно несколькими нитями. Как вариант решения: Нужно завести 2 мютекса. 1. На изменение. 2. На чтение. Если флаг(мютекс) на чтение установлен, никакая нить ничего изменять не может. Зато все нити могут читать паралельно. Если установлен флаг(мютекс) на изменение то никто кроме единственной изменяющей нити не может производить никаких действий с обьектом. Не забудьте хранить и актуализировать количество паралельно читающих нитей. Вероятнее всего нужно будет создавать систему приоритетов, потому как пишущей нити будет очень тяжело забрать ресурс у нескольких перманетно читающих нитей. Также нужно контролировать атомарность измениния всей группы флагов(мютексов) защитив ее всю еще одним. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 11:41 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
onstat- пишет: > Как вариант решения: > Нужно завести 2 мютекса. > 1. На изменение. > 2. На чтение. .... > будет очень тяжело забрать ресурс у нескольких перманетно читающих нитей. > Также нужно контролировать атомарность измениния всей группы > флагов(мютексов) > защитив ее всю еще одним. Что-то сложновато как-то, да и не будет работать эта логика. Мьютексов надо иметь только один, а вот вид блокировки контейнера - трех видов. Чтение, требование записи и запись. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 13:49 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
OLEG_2005 пишет: > Если я при переборе контейнера буду брать очередной элемент под > мьютексом, то при переходе к следующему элементу нет гарантии Еще раз что я предлагал. В цикле переменной цикла является i - номер элемента. В векторе или в последовательном контейнере. внутри тела цикла сначала захватывается мьютекс контейнера находится i-ый элемент. если не находится, мьютекс освобождается и цикл заканчивается. Он копируется куда-то, где потом будет использоваться. итераторы, если они использовались для поиска, уничтожаются (т.е. более не используются). освобождается мьютекс выполняется обработка скопированного элемента. цикл продолжается, увеличивается i. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 13:55 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
MasterZiv onstat- пишет: > Как вариант решения: > Нужно завести 2 мютекса. > 1. На изменение. > 2. На чтение. .... > будет очень тяжело забрать ресурс у нескольких перманетно читающих нитей. > Также нужно контролировать атомарность измениния всей группы > флагов(мютексов) > защитив ее всю еще одним. Что-то сложновато как-то, да и не будет работать эта логика. Мьютексов надо иметь только один, а вот вид блокировки контейнера - трех видов. Чтение, требование записи и запись. Posted via ActualForum NNTP Server 1.4 Почему только один? Я не силен в тредах. В Unix на семафорах у меня такое работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 14:05 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
onstat- пишет: > Почему только один? Я не силен в тредах. Я не буду отвечать. Ты лучше вместо этого опиши полностью подробно как предлагаешь это сделать. Но только IMHO не будет это полезно вопрошающему. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 14:19 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
MasterZiv Что-то сложновато как-то, да и не будет работать эта логика. почему не будет? 1. Проверяем мютексы на чтение ( с учетом приоритетности записи) и на запись, если кто то пишет ( или прриоритет записи высокий), спим пока не освободится. 2. Взводим мютекс защищающий группу(либо спим пока его не освободит другая нить). 3. Пытаемся установить флаг чтения либо записи. Если запись уже идет, либо кто то читает если нужно писать, не спим, повышаем приоритет записи, освобождаем мютекс защищающий группу, и переходим на п 1. Если чтение возможно увеличиваем счетчик читающих на единицу. Если приоритет записи выше нужного освобождаем мютекс группы и переходим на п 1. 4. освобождаем мютекс защищающий группу. 5.Делаем необходимые действия. 6. Взводим мютекс защиты группы, 7.Освобождаем мютексы записи/чтения но стачала уменьшаем счетчик читающих( если читали) или приоритет записи( если писали). 8. Освобождаем мютекс защиты группы. Подскажите где я не прав. На POSIX семафорах это реализовать проще, операция semop гарантирует атомарность (чтения) изменения всего набора(группы) семафоров . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 14:33 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
blindedНу вообще-то нужен 1 mutex и 2 счетчика Если будет один мютекс , нужно будет принудительно усыплять и будить нити. Если их будет несколько процесс сна можно будет автоматизировать( спать на мютексах) и просыпаться автоматом когда мютексы будут сброшены. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 14:47 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
onstat- пишет: > Если будет один мютекс , нужно будет принудительно усыплять и будить нити. > Если их будет несколько процесс сна можно будет автоматизировать( спать > на мютексах) и просыпаться автоматом когда мютексы будут сброшены. Да, это правильное замечание. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 17:23 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
OLEG_2005 Если я при переборе контейнера буду брать очередной элемент под мьютексом, то при переходе к следующему элементу нет гарантии правильности итератора (после особождения от мьютекса итератор может стать недействительным). Или я неправ? Я могу заблуждаться . Для безопасного доступа к вектору нужно пользоваться не итератором, а оператором []. Это вносит неудобства, но целостность должно гарантировать. По поводу защиты. Изменение может быть двух видов 1. Изменение размера контейнера, для этого можно воспользоваться предложенным мною выше. 2. Изменение элемента контейнера, В этом случае для всех нитей можно завести общий список изменяемых обьектов в данный момент, и изменять разные элементы паралельно. При этом на весь контейнер нужно ставить мутекс на чтение, а непосредственно изменяемый элемент защищать мутексом на запись. ИЛИ Что бы не держать мутексы по количеству элементов можно создать пул мутексов и привязывать из него мутекс к конкретному изменяемому в данный момент элементу, количество мутексов в пуле должно быть приблизительно равно количеству одновреммено изменяемых элементов за одну транзакцию умноженное на количество нитей. Если в пуле свободных мутексов нет, то спать пока они не появятся в нужном количестве. Как идея? Продумать нужно, иначе борьба с дедлоками в конечном итоге может все похоронить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 20:36 |
|
||
|
контейнеры STL и многопоточность
|
|||
|---|---|---|---|
|
#18+
onstat- пишет: > почему не будет? .... > Подскажите где я не прав. Вот что б я чего-то там понял. Разве этого не достаточно ? > 1. Проверяем мютексы на чтение и на запись, > если кто то пишет, спим пока не освободится. делаем дело, освобождаем мьютексы. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.05.2007, 20:44 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=34559993&tid=2028679]: |
0ms |
get settings: |
9ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
177ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
84ms |
get tp. blocked users: |
1ms |
| others: | 213ms |
| total: | 519ms |

| 0 / 0 |
