Выше VS2015, с / Zc: threadSafeInit, инициализация статического локального varibal является поточно-ориентированной, но MSDN сказал
Потоково-безопасные статические локальные переменные используют внутреннее хранилище потоков (TLS) для обеспечения эффективного выполнения, когда статический объект уже инициализирован.
xp игнорирует сегмент .tls, если динамическая загрузка dll с LoadLibrary
так
- зачем использовать tls и как это работает
efficient
?
- использует ли std :: call_once tls?
- как реализовать thread-safe-init без tls?
Ссылка цитаты находится здесь Потоковая безопасная локальная статическая инициализация
Реализация этой функции зависит от функций поддержки операционной системы Windows в Windows Vista и более поздних операционных системах. Windows XP, Windows Server 2003 и более старые операционные системы не имеют такой поддержки, поэтому они не получают преимущества в эффективности.
мой тестовый код:
class AA
{
public:
int m_a = 1;
};
AA* getAA()
{
static AA a;
return &a;
}
int main()
{
AA* pa = getAA();
return 0;
}
с /Zc:threadSafeInit
, функция getAA
в разборке:
008c1000 55 push ebp
008c1001 8bec mov ebp,esp
008c1003 64a12c000000 mov eax,dword ptr fs:[0000002Ch]
008c1009 8b08 mov ecx,dword ptr [eax]
008c100b 8b15b8338c00 mov edx,dword ptr [testStatic!__favor+0x4 (008c33b8)]
008c1011 3b9104000000 cmp edx,dword ptr [ecx+4]
008c1017 7e2d jle testStatic!getAA+0x46 (008c1046)
008c1019 68b8338c00 push offset testStatic!__favor+0x4 (008c33b8)
008c101e e809020000 call testStatic!_Init_thread_header (008c122c)
008c1023 83c404 add esp,4
008c1026 833db8338c00ff cmp dword ptr [testStatic!__favor+0x4 (008c33b8)],0FFFFFFFFh
008c102d 7517 jne testStatic!getAA+0x46 (008c1046)
008c102f b9bc338c00 mov ecx,offset testStatic!a (008c33bc)
008c1034 e817000000 call testStatic!AA::AA (008c1050)
008c1039 68b8338c00 push offset testStatic!__favor+0x4 (008c33b8)
008c103e e89f010000 call testStatic!_Init_thread_footer (008c11e2)
008c1043 83c404 add esp,4
008c1046 b8bc338c00 mov eax,offset testStatic!a (008c33bc)
008c104b 5d pop ebp
008c104c c3 ret
и /Zc:threadSafeInit-
(закрыть функцию), функция getAA
в разборке:
010e1000 55 push ebp
010e1001 8bec mov ebp,esp
010e1003 a180330e01 mov eax,dword ptr [testStatic!a+0x4 (010e3380)]
010e1008 83e001 and eax,1
010e100b 7519 jne testStatic!getAA+0x26 (010e1026)
010e100d 8b0d80330e01 mov ecx,dword ptr [testStatic!a+0x4 (010e3380)]
010e1013 83c901 or ecx,1
010e1016 890d80330e01 mov dword ptr [testStatic!a+0x4 (010e3380)],ecx
010e101c b97c330e01 mov ecx,offset testStatic!a (010e337c)
010e1021 e80a000000 call testStatic!AA::AA (010e1030)
010e1026 b87c330e01 mov eax,offset testStatic!a (010e337c)
010e102b 5d pop ebp
010e102c c3 ret