Я знаю, что контейнеры из стандартной библиотеки не являются потокобезопасными. . При этом я привык думать, что к контейнеру, скажем типа std :: list
, нельзя получить доступ одновременно более чем одним потоком (некоторые из которых могут изменять контейнер). Но теперь кажется, что это нечто большее, чем кажется на первый взгляд; что-то более тонкое, что-то не столь очевидное, по крайней мере для меня.
Например, рассмотрим эту функцию, которая принимает первый аргумент по значению :
void log(std::string msg, severity s, /*...*/)
{
return; //no code!
}
Является ли это потокобезопасным?
Сначала кажется, что это потокобезопасный, поскольку тело функции не имеет доступа к общим изменяемым ресурсам, следовательно, поточно-ориентированным. Поразмыслив, мне приходит в голову, что при вызове такой функции будет создан объект типа std :: string
, который является первым аргументом, и я думаю, что создание этого объекта не поточно-ориентированный, поскольку он внутренне использует std :: allocator
, что, как я считаю, не является поточно-ориентированным. Следовательно, вызов такой функции также не является потокобезопасным.Но если верно, то как насчет этого:
void f()
{
std::string msg = "message"; //is it thread-safe? it doesn't seem so!
}
Правильно ли я иду? Можем ли мы использовать std :: string
(или любой контейнер, который использует std :: allocator
внутри) в многопоточной программе?
Я конкретно говорю о контейнерах как локальных переменных , в отличие от общих объектов.
Я искал в Google и нашел много похожих сомнений, но без конкретного ответа. У меня такая же проблема, как и у него:
Пожалуйста, рассмотрите оба варианта: C ++ 03 и C ++ 11.