Если мы имеем дело с несколькими потоками, один из которых добавляет и удаляет элементы в список (std::list) а другой работает с этими элементами, то будет ли он более безопасен в плане access violation чем std::map.
Я вот о чем говорю.
Допустим один поток делает push_back and erase, а в другом такая функция
void Server::Send ()
{
iter = list.begin();
for (; iter != list.end(); ++iter)
{
sendInfo (iter->iSocket);
}
}
Ведь по идее если использовать map и при работе этой функции вставится или удалится элемент, то итератор может стать недействительноым из за перелокации элементов. А список по идее не трогает другие элементы при вставке или удалении. Я понимаю что до конца защищено не будет, но все же..
Re: Безопаснее ли список чем словарь
От:
Аноним
Дата:
12.03.06 21:55
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Если мы имеем дело с несколькими потоками, один из которых добавляет и удаляет элементы в список (std::list) а другой работает с этими элементами, то будет ли он более безопасен в плане access violation чем std::map.
Нет, не будет.
Доступ к разделяемым ресурсам надо синхронизировать.
Это общее правило в многопоточных приложениях.
Работаешь ли ты с map или list нет никакой разницы в этом смысле.
Контейнеры STL не являются потокобезопасными со всеми вытекающими последствиями.
" Аноним " <0@users.rsdn.ru> сообщил/сообщила в новостях следующее: news:1777268@news.rsdn.ru... > Если мы имеем дело с несколькими потоками, один из которых добавляет и удаляет элементы в список (std::list) а другой работает с этими элементами, то будет ли он более безопасен в плане access violation чем std::map. > > Я вот о чем говорю. > > Допустим один поток делает push_back and erase, а в другом такая функция > > >
> void Server::Send ()
> {
>
> iter = list.begin();
> for (; iter != list.end(); ++iter)
> {
> sendInfo (iter->iSocket);
> }
> }
>
> > > Ведь по идее если использовать map и при работе этой функции вставится или удалится элемент, то итератор может стать недействительноым из за перелокации элементов. А список по идее не трогает другие элементы при вставке или удалении. Я понимаю что до конца защищено не будет, но все же..
И map и list в этом плане равнозначны. При операциях удаления и вставки существующие итераторы на другие элементы остаются действительными. В приведенном примере итератор может стать недействительным не из за переаллокации элементов, а из за того, что в другом потоке может удаляться тот элемент, который в данный момент обрабатывается в данном потоке. Поэтому, независимо от того, используем мы map или list, доступ к контейнеру из разных потоков в этом случае нужно синхронизовать.
Posted via RSDN NNTP Server 2.0
--
Справедливость выше закона. А человечность выше справедливости.
Re: Безопаснее ли список чем словарь
От:
Аноним
Дата:
14.03.06 00:23
Оценка:
Здравствуйте, Аноним, Вы писали:
Подскажите как правильно защитить мап в моем случае. Вот код (синтаксические мелочи языка опущены)
// один потокvoid Socket::getData ()
{
// в этой функции обрабатываются socket messages. Я использую асинхронный сокет
LockGuard lg (mutex); // здесь запираю мутексswitch (message)
{
case FD_READ:
pOwner->Read ();
break;
case FD_WRITE:
pOwner->Write ();
break;
........
}
}
// главный поток тутvoid Dialog::Read ()
{
.......
if (добавить клиента)
map[key] = value;
else if (удалить клиента)
map.erase (...);
else if (послать сообщение клиентам)
SendToClients ();
}
void Dialog::SendToClients ()
{
iter = map.begin();
for (...)
send (iter->first); // посылаем на сокет клиента (дескриптор сокета - ключ мапа)
}
Иногда приложение падает на функции SendToClients. Я думаю, что это происходит из за того что вторичный поток вмешаивается когда происходит рассылка сообщения и перестраивает словарь. Но вроде во вторичном потоке стоит запертый мутекс и это значит что пока не обработается до конца сообщение от сокета, то другого сообщения не будет обрабатываться...Нужно ли как то дополнительно защищать мап?
Re[2]: Безопаснее ли список чем словарь
От:
Аноним
Дата:
14.03.06 08:10
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Иногда приложение падает на функции SendToClients. Я думаю, что это происходит из за того что вторичный поток вмешаивается когда происходит рассылка сообщения и перестраивает словарь.
Скорей всего так и есть.
А>Но вроде во вторичном потоке стоит запертый мутекс и это значит что пока не обработается до конца сообщение от сокета, то другого сообщения не будет обрабатываться...Нужно ли как то дополнительно защищать мап?
Мьютекс у тебя стоит только на Socket::getData.
Это означает, что только этот метод безопасно вызывать из разных потоков.
А другие то методы никак не защищены и запросто возможна ситуцация,
когда у тебя одновременно работают все 3 метода getData, Read и SendToClients
и еще возможно другие методы...
Тем же самым мьютексом надо защищать и все другие методы.
Т.е. как только один из методов захватил мьютекс, другие будут ждать...
Re[3]: Безопаснее ли список чем словарь
От:
Аноним
Дата:
14.03.06 13:07
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Аноним, Вы писали:
>Мьютекс у тебя стоит только на Socket::getData. А>Это означает, что только этот метод безопасно вызывать из разных потоков. А>А другие то методы никак не защищены и запросто возможна ситуцация,
другие методы вызываются из метода getData. то есть пока другие методы все не пройдут , getData не вернет контроль. А раз управление находится в getData за мьютексом, то по идее никакие следующие вызовы getData не должны вызываться.
А>Тем же самым мьютексом надо защищать и все другие методы. А>Т.е. как только один из методов захватил мьютекс, другие будут ждать...
я так делал. ЧЕрез некоторое время программа зависала.
Re[4]: Безопаснее ли список чем словарь
От:
Аноним
Дата:
14.03.06 23:43
Оценка:
Здравствуйте, Аноним, Вы писали:
А>>Тем же самым мьютексом надо защищать и все другие методы. А>>Т.е. как только один из методов захватил мьютекс, другие будут ждать...
А>я так делал. ЧЕрез некоторое время программа зависала.
Это называется deadlock
Стандартная проблема при многопоточном программировании.
Защищать методы надо осознанно.
Если просто тупо навтыкать мьютексов куда попало,
то гарантированно наткнешся на deadlock.
В общем — это опыт, который со временем придет
Нарисуй для себя диаграммку, что, как и когда вызывается.
Тогда будет легче понять, как разрулить ситуацию.
Твоя проблема в общем к С++ прямого отношения не имеет.