Я знаю, что контейнеры из стандартной библиотеки не являются потокобезопасными. При этом я думал, что контейнер, например тип 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 и нашел много подобных сомнений, без конкретного ответа. Я сталкиваюсь с аналогичной проблемой, как и его:
Пожалуйста, рассмотрите С++ 03 и С++ 11, оба.