Мне известно о том, что контейнеры из стандартной библиотеки не являются поточно-ориентированными. Раньше я думал, что контейнер, скажем, типа 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, оба.