Класс или шаблон, аналогичный 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, синхронизации, это не "лечится".
Здравствуйте, aid2003, Вы писали:
A>В МСДНе не понятно написано
НЕТ в общем понимании, но с оговоркой что он потокобезопасен для операции чтения например. Т.е. если несколько потоков будут одновременно читать из него. Не помню где это видел, вроде даже в стандарте.
Здравствуйте, Denwer, Вы писали:
D>Здравствуйте, aid2003, Вы писали:
A>>В МСДНе не понятно написано
D>НЕТ в общем понимании, но с оговоркой что он потокобезопасен для операции чтения например. Т.е. если несколько потоков будут одновременно читать из него. Не помню где это видел, вроде даже в стандарте.
Ну, в стандарте о thread safety вообще ни слоыва нету
А свойством потокобезопасноти для операция чтения, обладают, например реализации STL от SGI и STLPort
Здравствуйте, aid2003, Вы писали:
A>В МСДНе не понятно написано
Всё зависит от реализации. В стандарте требование к потокобезопасности не указано.
Те реализации, что идут с VC, Builder`ом не являются.
Осмеюсь предположить, что Boost, stlport, Dinkumware и HP вроде тоже таковыми не являются, поправьте, если я не прав — просто их я не юзал
Вообще максимум, на что можно надеяться — это безопасность параллельного чтения, безопасность параллельной записи в разные контейнеры. По утверждению Мейерса — это "золотой стандарт" поддержки многопоточности в контейнерах STL, котоый был введён в SGI и которым пользуется большинство разработчиков.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Mr. None, Вы писали:
MN>Здравствуйте, aid2003, Вы писали:
A>>В МСДНе не понятно написано
MN>Всё зависит от реализации. В стандарте требование к потокобезопасности не указано. MN>Те реализации, что идут с VC, Builder`ом не являются. MN>Осмеюсь предположить, что Boost, stlport, Dinkumware и HP вроде тоже таковыми не являются, поправьте, если я не прав — просто их я не юзал
MN>Вообще максимум, на что можно надеяться — это безопасность параллельного чтения, безопасность параллельной записи в разные контейнеры. По утверждению Мейерса — это "золотой стандарт" поддержки многопоточности в контейнерах STL, котоый был введён в SGI и которым пользуется большинство разработчиков.
А если аппелировать к своему опыту, то синхронизировать в многопоточной среде приходиться всё. Один раз понадеялся, что метод deque::size() будет потокобезопасным в том смысле, что он мне вернёт хотя-бы предыдущее значение... ага... сейчас полдня ошибку ловил — он мне чуть ли не рандомайзом генерил значения
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Denwer, Вы писали:
D>>Здравствуйте, aid2003, Вы писали:
A>>>В МСДНе не понятно написано
D>>НЕТ в общем понимании, но с оговоркой что он потокобезопасен для операции чтения например. Т.е. если несколько потоков будут одновременно читать из него. Не помню где это видел, вроде даже в стандарте.
B>Ну, в стандарте о thread safety вообще ни слоыва нету B>А свойством потокобезопасноти для операция чтения, обладают, например реализации STL от SGI и STLPort
Здравствуйте, aid2003, Вы писали:
A>В МСДНе не понятно написано
Вроде понятно написано...
Если у тебя есть хоть один читающий поток, то запись из другого потока в тот же вектор небезопасна.
В таком случае требуется пользоваться критическими секциями.
MN>А если аппелировать к своему опыту, то синхронизировать в многопоточной среде приходиться всё. Один раз понадеялся, что метод deque::size() будет потокобезопасным в том смысле, что он мне вернёт хотя-бы предыдущее значение... ага... сейчас полдня ошибку ловил — он мне чуть ли не рандомайзом генерил значения
Фраза "хотя-бы предыдущее значение" говорит о том, что это значение может изменяться, а значит присутствует пишущий поток, а значит претензии к потокобезопасности в данном случае необоснованы.
Или я что-то упустил?
Здравствуйте, Mr. None, Вы писали:
MN>А если аппелировать к своему опыту, то синхронизировать в многопоточной среде приходиться всё. Один раз понадеялся, что метод deque::size() будет потокобезопасным в том смысле, что он мне вернёт хотя-бы предыдущее значение... ага... сейчас полдня ошибку ловил — он мне чуть ли не рандомайзом генерил значения
А не скрал ли ты от нас правду, скорее всего ты где то еще и писал туда.
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Mr. None, Вы писали:
MN>>А если аппелировать к своему опыту, то синхронизировать в многопоточной среде приходиться всё. Один раз понадеялся, что метод deque::size() будет потокобезопасным в том смысле, что он мне вернёт хотя-бы предыдущее значение... ага... сейчас полдня ошибку ловил — он мне чуть ли не рандомайзом генерил значения
B>Фраза "хотя-бы предыдущее значение" говорит о том, что это значение может изменяться, а значит присутствует пишущий поток, а значит претензии к потокобезопасности в данном случае необоснованы. B>Или я что-то упустил?
Всё правильно, был параллельный поток, который писал, но меня вполне устроило бы и предыдущее значение. То есть я рассуждал так: ну и не хай кто-то пишет, я получу либо новое значение, либо предыдущее (молодой был — зелёный ), но кто же знал, что значения будут отличаться настолько!!!
Согласен — претензия необоснованы, просто хотел привести пример, что какие-то предположения или рассуждения могут оказаться чреваты.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Reyst, Вы писали:
R>Здравствуйте, aid2003, Вы писали:
A>>В МСДНе не понятно написано
R>Вроде понятно написано... R>Если у тебя есть хоть один читающий поток, то запись из другого потока в тот же вектор небезопасна. R>В таком случае требуется пользоваться критическими секциями.
Более того скажу... даже чтение небезопасно, причём не только значений, но и каких-то параметров, например, size() — см. выше !
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Mr. None, Вы писали:
MN>Согласен — претензия необоснованы, просто хотел привести пример, что какие-то предположения или рассуждения могут оказаться чреваты.
Эти предположения или рассуждения должны быть логическими, а не с неба взятыми.
Здравствуйте, Denwer, Вы писали:
D>Здравствуйте, Mr. None, Вы писали:
MN>>Согласен — претензия необоснованы, просто хотел привести пример, что какие-то предположения или рассуждения могут оказаться чреваты.
D>Эти предположения или рассуждения должны быть логическими, а не с неба взятыми.
Вот именно в этом я и убедился
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
MN>Более того скажу... даже чтение небезопасно, причём не только значений, но и каких-то параметров, например, size() — см. выше !
Это где это чтение size() небезопасно при отсутствии записи из других потоков?
Как говорят, код в студию... (и используемую реализацию STL).
Я вам не скажу за всю Одессу, но в стандартных STL от VS6, VS2002, VS2003 (о чем, собственно, в вопросе и идет речь) чтение из нескольких потоков абсолютно безопасно.
При наличии записи, естественно, существуют "ограничения", любые операции записи нужно "обертывать".
Здравствуйте, Reyst, Вы писали:
R>Здравствуйте, Mr. None, Вы писали:
MN>>Более того скажу... даже чтение небезопасно, причём не только значений, но и каких-то параметров, например, size() — см. выше !
R>Это где это чтение size() небезопасно при отсутствии записи из других потоков? R>Как говорят, код в студию... (и используемую реализацию STL).
Я имел ввиду, что чтение из контейнера небезопасно, если кто-то в него пишет. Причём может быть небезопасным даже, скажем, получение размера контейнера методом size().
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Denwer, Вы писали:
D>Здравствуйте, Reyst, Вы писали:
R>>При наличии записи, естественно, существуют "ограничения", любые операции записи нужно "обертывать".
D>Немного подправлю: При наличии записи, естественно, существуют "ограничения", любые операции нужно "обертывать".
D>ЗЫ: последнее слово ЗАПИСИ не нужно
ЗЫ: Смотря как "обертывать". Если на время записи блокируются все читающие потоки, то зачем огород городить?
Здравствуйте, Mr. None, Вы писали:
MN>Я имел ввиду, что чтение из контейнера небезопасно, если кто-то в него пишет. Причём может быть небезопасным даже, скажем, получение размера контейнера методом size().
А я что говорю?!
А вообще мы сильно отошли от исходного вопроса и я предлагаю поставить точку.
Пара последних замечаний:
1) Любая реализация "полной" (?!) потокобезопасности (включая предлагаемую "потокобезопасную очередь", хотя я ее и не видел) гарантированно нарушает основные требования STL по эффективности операций (по крайней мере, на имеющихся процессорах).
2) В случае "своей" разработки эффективнее решать вопросы потокобезопасности при операциях записи, а не при каждом доступе к контейнеру.
3) В случае использования "чужого" кода также скорее всего будет лучше пересмотреть этот чужой код, вместо очень неэффективного "надевания презерватива" на любую операцию чтения.
Здравствуйте, Mr. None, Вы писали:
MN>Здравствуйте, Reyst, Вы писали:
R>>Здравствуйте, aid2003, Вы писали:
MN>В своё время я написал небольшой шаблон — потокобезопасная очередь. Если надо, давай мыло, скину — выложить в сеть некуда .