STL-вский vector и снихронизация потоков
От: RealBobEx  
Дата: 04.08.05 09:23
Оценка:
Привет всем!
Читал я дискуссию по поводу потокобезопасности 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.
    }

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