Потокобезопасен ли класс std::vector ?
От: Павел Кузнецов  
Дата: 01.04.04 05:47
Оценка: 6 (1)
#Имя: FAQ.cpp.stl.vector.multithread
A>В МСДНе не понятно написано

Класс или шаблон, аналогичный std::vector по интерфейсу, сделать "потокобезопасным" сам по себе невозможно по принципиальным соображениям. Например:
void f(std::vector<int>& v)
{
  std::size_t sz = v.size();
  for (std::size_t i = 0; i < sz; ++i)
    std::cout << v[[i];
}

Вне зависимости от степени "потокобезопасности" std::vector, без дополнительной синхронизации, функция f не будет "потокобезопасной", если есть хотя бы один поток, который может модифицировать v одновременно с выполнением f. В самом деле: если после получения v.size() другой поток, например, уменьшит размер вектора, то произойдет обращение к "чужой" памяти.

Никак, кроме "нормальной", внешней по отношению к std::vector, синхронизации, это не "лечится".

--
Павел Кузнецов
MetaCommunications Engineering
http://www.meta-comm.com/engineering/
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Потокобезопасен ли класс std::vector ?
От: Шахтер Интернет  
Дата: 02.04.04 02:14
Оценка: +1
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Павел Кузнецов

ПК>MetaCommunications Engineering
ПК>http://www.meta-comm.com/engineering/


<offtop>

ЭЭЭ. Я правильно понимаю, что можно поздравлять с новым местом работы?

</offtop>
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Потокобезопасен ли класс std::vector ?
От: aid2003  
Дата: 31.03.04 06:14
Оценка:
В МСДНе не понятно написано
Re: Потокобезопасен ли класс std::vector ?
От: c-smile Канада http://terrainformatica.com
Дата: 31.03.04 06:24
Оценка:
Здравствуйте, aid2003, Вы писали:

A>В МСДНе не понятно написано


Открой исходник и глянь. И снизойдет на тя благодать...

Увы, вся STL не безопасна в плане потоков. By design.

Но это не означает что ея нельзя использовать а многопоточной среде.
Можно только осторожно.
Re: Потокобезопасен ли класс std::vector ?
От: Denwer Россия  
Дата: 31.03.04 06:25
Оценка:
Здравствуйте, aid2003, Вы писали:

A>В МСДНе не понятно написано


НЕТ в общем понимании, но с оговоркой что он потокобезопасен для операции чтения например. Т.е. если несколько потоков будут одновременно читать из него. Не помню где это видел, вроде даже в стандарте.
Re[2]: Потокобезопасен ли класс std::vector ?
От: Bell Россия  
Дата: 31.03.04 06:32
Оценка:
Здравствуйте, Denwer, Вы писали:

D>Здравствуйте, aid2003, Вы писали:


A>>В МСДНе не понятно написано


D>НЕТ в общем понимании, но с оговоркой что он потокобезопасен для операции чтения например. Т.е. если несколько потоков будут одновременно читать из него. Не помню где это видел, вроде даже в стандарте.


Ну, в стандарте о thread safety вообще ни слоыва нету
А свойством потокобезопасноти для операция чтения, обладают, например реализации STL от SGI и STLPort
Любите книгу — источник знаний (с) М.Горький
Re: Потокобезопасен ли класс std::vector ?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 31.03.04 06:34
Оценка:
Здравствуйте, aid2003, Вы писали:

A>В МСДНе не понятно написано


Всё зависит от реализации. В стандарте требование к потокобезопасности не указано.
Те реализации, что идут с VC, Builder`ом не являются.
Осмеюсь предположить, что Boost, stlport, Dinkumware и HP вроде тоже таковыми не являются, поправьте, если я не прав — просто их я не юзал

Вообще максимум, на что можно надеяться — это безопасность параллельного чтения, безопасность параллельной записи в разные контейнеры. По утверждению Мейерса — это "золотой стандарт" поддержки многопоточности в контейнерах STL, котоый был введён в SGI и которым пользуется большинство разработчиков.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[2]: Потокобезопасен ли класс std::vector ?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 31.03.04 06:37
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>Здравствуйте, aid2003, Вы писали:


A>>В МСДНе не понятно написано


MN>Всё зависит от реализации. В стандарте требование к потокобезопасности не указано.

MN>Те реализации, что идут с VC, Builder`ом не являются.
MN>Осмеюсь предположить, что Boost, stlport, Dinkumware и HP вроде тоже таковыми не являются, поправьте, если я не прав — просто их я не юзал

MN>Вообще максимум, на что можно надеяться — это безопасность параллельного чтения, безопасность параллельной записи в разные контейнеры. По утверждению Мейерса — это "золотой стандарт" поддержки многопоточности в контейнерах STL, котоый был введён в SGI и которым пользуется большинство разработчиков.


А если аппелировать к своему опыту, то синхронизировать в многопоточной среде приходиться всё. Один раз понадеялся, что метод deque::size() будет потокобезопасным в том смысле, что он мне вернёт хотя-бы предыдущее значение... ага... сейчас полдня ошибку ловил — он мне чуть ли не рандомайзом генерил значения
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[3]: Потокобезопасен ли класс std::vector ?
От: Denwer Россия  
Дата: 31.03.04 06:37
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Denwer, Вы писали:


D>>Здравствуйте, aid2003, Вы писали:


A>>>В МСДНе не понятно написано


D>>НЕТ в общем понимании, но с оговоркой что он потокобезопасен для операции чтения например. Т.е. если несколько потоков будут одновременно читать из него. Не помню где это видел, вроде даже в стандарте.


B>Ну, в стандарте о thread safety вообще ни слоыва нету

B>А свойством потокобезопасноти для операция чтения, обладают, например реализации STL от SGI и STLPort

Точно, вот на ихнем сайте я это и читал
Re: Потокобезопасен ли класс std::vector ?
От: Reyst Россия  
Дата: 31.03.04 06:40
Оценка:
Здравствуйте, aid2003, Вы писали:

A>В МСДНе не понятно написано


Вроде понятно написано...
Если у тебя есть хоть один читающий поток, то запись из другого потока в тот же вектор небезопасна.
В таком случае требуется пользоваться критическими секциями.
AR << RSDN@Home 1.1.3 stable >>
Re[3]: Потокобезопасен ли класс std::vector ?
От: Bell Россия  
Дата: 31.03.04 06:46
Оценка:
Здравствуйте, Mr. None, Вы писали:


MN>А если аппелировать к своему опыту, то синхронизировать в многопоточной среде приходиться всё. Один раз понадеялся, что метод deque::size() будет потокобезопасным в том смысле, что он мне вернёт хотя-бы предыдущее значение... ага... сейчас полдня ошибку ловил — он мне чуть ли не рандомайзом генерил значения


Фраза "хотя-бы предыдущее значение" говорит о том, что это значение может изменяться, а значит присутствует пишущий поток, а значит претензии к потокобезопасности в данном случае необоснованы.
Или я что-то упустил?
Любите книгу — источник знаний (с) М.Горький
Re[3]: Потокобезопасен ли класс std::vector ?
От: Denwer Россия  
Дата: 31.03.04 06:48
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>А если аппелировать к своему опыту, то синхронизировать в многопоточной среде приходиться всё. Один раз понадеялся, что метод deque::size() будет потокобезопасным в том смысле, что он мне вернёт хотя-бы предыдущее значение... ага... сейчас полдня ошибку ловил — он мне чуть ли не рандомайзом генерил значения


А не скрал ли ты от нас правду, скорее всего ты где то еще и писал туда.
Re[4]: Потокобезопасен ли класс std::vector ?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 31.03.04 06:54
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Mr. None, Вы писали:



MN>>А если аппелировать к своему опыту, то синхронизировать в многопоточной среде приходиться всё. Один раз понадеялся, что метод deque::size() будет потокобезопасным в том смысле, что он мне вернёт хотя-бы предыдущее значение... ага... сейчас полдня ошибку ловил — он мне чуть ли не рандомайзом генерил значения


B>Фраза "хотя-бы предыдущее значение" говорит о том, что это значение может изменяться, а значит присутствует пишущий поток, а значит претензии к потокобезопасности в данном случае необоснованы.

B>Или я что-то упустил?

Всё правильно, был параллельный поток, который писал, но меня вполне устроило бы и предыдущее значение. То есть я рассуждал так: ну и не хай кто-то пишет, я получу либо новое значение, либо предыдущее (молодой был — зелёный ), но кто же знал, что значения будут отличаться настолько!!!

Согласен — претензия необоснованы, просто хотел привести пример, что какие-то предположения или рассуждения могут оказаться чреваты.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[2]: Потокобезопасен ли класс std::vector ?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 31.03.04 06:56
Оценка:
Здравствуйте, Reyst, Вы писали:

R>Здравствуйте, aid2003, Вы писали:


A>>В МСДНе не понятно написано


R>Вроде понятно написано...

R>Если у тебя есть хоть один читающий поток, то запись из другого потока в тот же вектор небезопасна.
R>В таком случае требуется пользоваться критическими секциями.

Более того скажу... даже чтение небезопасно, причём не только значений, но и каких-то параметров, например, size() — см. выше !
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[5]: Потокобезопасен ли класс std::vector ?
От: Denwer Россия  
Дата: 31.03.04 07:00
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>Согласен — претензия необоснованы, просто хотел привести пример, что какие-то предположения или рассуждения могут оказаться чреваты.


Эти предположения или рассуждения должны быть логическими, а не с неба взятыми.
Re[6]: Потокобезопасен ли класс std::vector ?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 31.03.04 07:04
Оценка:
Здравствуйте, Denwer, Вы писали:

D>Здравствуйте, Mr. None, Вы писали:


MN>>Согласен — претензия необоснованы, просто хотел привести пример, что какие-то предположения или рассуждения могут оказаться чреваты.


D>Эти предположения или рассуждения должны быть логическими, а не с неба взятыми.


Вот именно в этом я и убедился
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[2]: Потокобезопасен ли класс std::vector ?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 31.03.04 07:06
Оценка:
Здравствуйте, Reyst, Вы писали:

R>Здравствуйте, aid2003, Вы писали:


В своё время я написал небольшой шаблон — потокобезопасная очередь. Если надо, давай мыло, скину — выложить в сеть некуда .
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[3]: Потокобезопасен ли класс std::vector ?
От: Reyst Россия  
Дата: 31.03.04 07:07
Оценка:
Здравствуйте, Mr. None, Вы писали:


MN>Более того скажу... даже чтение небезопасно, причём не только значений, но и каких-то параметров, например, size() — см. выше !


Это где это чтение size() небезопасно при отсутствии записи из других потоков?
Как говорят, код в студию... (и используемую реализацию STL).

Я вам не скажу за всю Одессу, но в стандартных STL от VS6, VS2002, VS2003 (о чем, собственно, в вопросе и идет речь) чтение из нескольких потоков абсолютно безопасно.

При наличии записи, естественно, существуют "ограничения", любые операции записи нужно "обертывать".
AR << RSDN@Home 1.1.3 stable >>
Re[4]: Потокобезопасен ли класс std::vector ?
От: Denwer Россия  
Дата: 31.03.04 07:10
Оценка:
Здравствуйте, Reyst, Вы писали:

R>При наличии записи, естественно, существуют "ограничения", любые операции записи нужно "обертывать".


Немного подправлю: При наличии записи, естественно, существуют "ограничения", любые операции нужно "обертывать".

ЗЫ: последнее слово ЗАПИСИ не нужно
Re[4]: Потокобезопасен ли класс std::vector ?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 31.03.04 07:18
Оценка:
Здравствуйте, Reyst, Вы писали:

R>Здравствуйте, Mr. None, Вы писали:



MN>>Более того скажу... даже чтение небезопасно, причём не только значений, но и каких-то параметров, например, size() — см. выше !


R>Это где это чтение size() небезопасно при отсутствии записи из других потоков?

R>Как говорят, код в студию... (и используемую реализацию STL).

Я имел ввиду, что чтение из контейнера небезопасно, если кто-то в него пишет. Причём может быть небезопасным даже, скажем, получение размера контейнера методом size().
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[5]: Потокобезопасен ли класс std::vector ?
От: Reyst Россия  
Дата: 31.03.04 07:21
Оценка:
Здравствуйте, Denwer, Вы писали:

D>Здравствуйте, Reyst, Вы писали:


R>>При наличии записи, естественно, существуют "ограничения", любые операции записи нужно "обертывать".


D>Немного подправлю: При наличии записи, естественно, существуют "ограничения", любые операции нужно "обертывать".


D>ЗЫ: последнее слово ЗАПИСИ не нужно


ЗЫ: Смотря как "обертывать". Если на время записи блокируются все читающие потоки, то зачем огород городить?
AR << RSDN@Home 1.1.3 stable >>
Re[5]: Потокобезопасен ли класс std::vector ?
От: Reyst Россия  
Дата: 31.03.04 07:31
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>Я имел ввиду, что чтение из контейнера небезопасно, если кто-то в него пишет. Причём может быть небезопасным даже, скажем, получение размера контейнера методом size().


А я что говорю?!

А вообще мы сильно отошли от исходного вопроса и я предлагаю поставить точку.

Пара последних замечаний:
1) Любая реализация "полной" (?!) потокобезопасности (включая предлагаемую "потокобезопасную очередь", хотя я ее и не видел) гарантированно нарушает основные требования STL по эффективности операций (по крайней мере, на имеющихся процессорах).
2) В случае "своей" разработки эффективнее решать вопросы потокобезопасности при операциях записи, а не при каждом доступе к контейнеру.
3) В случае использования "чужого" кода также скорее всего будет лучше пересмотреть этот чужой код, вместо очень неэффективного "надевания презерватива" на любую операцию чтения.
AR << RSDN@Home 1.1.3 stable >>
Re[3]: Потокобезопасен ли класс std::vector ?
От: aid2003  
Дата: 31.03.04 16:52
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>Здравствуйте, Reyst, Вы писали:


R>>Здравствуйте, aid2003, Вы писали:


MN>В своё время я написал небольшой шаблон — потокобезопасная очередь. Если надо, давай мыло, скину — выложить в сеть некуда .


kllbzz@yandex.ru

заранее благодарен
Re[3]: Потокобезопасен ли класс std::vector ?
От: Павел Кузнецов  
Дата: 02.04.04 02:32
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>ЭЭЭ. Я правильно понимаю, что можно поздравлять с новым местом работы?


Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.