Привет всем!
Читал я дискуссию по поводу потокобезопасности vector-а и решил привести реальный пример, когда vector съезжает.
Ситауация такая:
Есть два потока, в одном кусок кода который пишет в вектор выглядит так:
singleLock.Lock();
m_Vector.push_back(/* некое значение */);
singleLock.Unlock();
sinleLock объявлен до начала цикла так:
CMyApp* pApp = (CMyApp*) AfxGetApp();
CSingleLock singleLock(&pApp->m_critSection);
Критикал секшн объявлена в объекте приложения (для простоты) так:
public:
CCriticalSection m_critSection;
Вектор объявлен во втором потоке:
vector<pair<basic_string<T>, LONG> > m_Vector;
В первый поток передается ссылка на него (или указатель).
Во втором потоке должен до завершения (т.е. до достижения vector.end()) отработать тестовый цикл:
vector<pair<basic_string<T>, LONG> >::iterator I;
CMyApp* pApp = (CMyApp*) AfxGetApp();
CSingleLock singleLock(&pApp->m_critSection);
long i = 0;
for(I = m_Vector.begin(); I < m_Vector.end(); I++)
{
singleLock.Lock();
TRACE("Index = %i\n", i);
i++;
singleLock.Unlock();
}
ЧТО ЖЕ происходит НА САМОМ ДЕЛЕ?
Итератор I указывает на несуществующее значение и при обращении (*m_Vector).first получаем ошибку и МАЛО ТОГО, цикл спокойно крутится до значений i гораздо больших чем m_Vector.size() — 1.
ВСЕ ЭТО РАБОТАЕТ только в том случае, если написать цикл иначе:
while(i < m_Vector.size())
{
//повторяем то же самое что и выше, только для поучения значений используем оператор
//m_Vector[i].first и m_Vector[i].second.
}
Кто-нибудь понимает почему съезжает итератор?
(Ооооочееннннь

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