gpt4 book ai didi

c++ - thread_local 单例默认执行惰性初始化?

转载 作者:行者123 更新时间:2023-11-30 03:22:04 35 4
gpt4 key购买 nike

我有以下 thread_local 单例代码:

struct Singl {
int& ref;

Singl(int& r) : ref(r) {}
~Singl() {}

void print() { std::cout << &ref << std::endl; }
};

static auto& singl(int& r) {
static thread_local Singl i(r);
return i;
}

int main() {
int x = 4;
singl(x).print();

int y = 55;
singl(y).print();

return 0;
}

此程序打印两次对 x 的引用。

编译器 ( gcc 8.1 on godbolt ) 似乎对单例对象进行了惰性初始化:

singl(int&):
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR fs:0
add rax, OFFSET FLAT:guard variable for singl(int&)::i@tpoff
movzx eax, BYTE PTR [rax]
test al, al
jne .L5
mov rax, QWORD PTR [rbp-8]
mov rdx, QWORD PTR fs:0
add rdx, OFFSET FLAT:singl(int&)::i@tpoff
mov rsi, rax
mov rdi, rdx
call Singl::Singl(int&)
mov rax, QWORD PTR fs:0
add rax, OFFSET FLAT:guard variable for singl(int&)::i@tpoff
mov BYTE PTR [rax], 1
mov rax, QWORD PTR fs:0
add rax, OFFSET FLAT:singl(int&)::i@tpoff
mov edx, OFFSET FLAT:__dso_handle
mov rsi, rax
mov edi, OFFSET FLAT:_ZN5SinglD1Ev
call __cxa_thread_atexit
.L5:
mov rax, QWORD PTR fs:0
add rax, OFFSET FLAT:singl(int&)::i@tpoff
leave
ret

每当我多次调用 singl 函数传递不同的参数时,这是我期望的默认行为吗?或者单例对象是否有可能在后续调用中被第二次初始化?

最佳答案

这确实是 guaranteed .当控制到达声明时,static/thread_local 局部变量只初始化一次。

需要注意的几点:

  1. 如果多个线程同时调用该函数,则只有一个线程执行初始化,其他线程等待。这就是反汇编中的保护变量正在做的事情。

  2. 如果初始化抛出异常,则认为未完成,将在下次控制到达时再次执行。

换句话说,它们_just work_™。

关于c++ - thread_local 单例默认执行惰性初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51515329/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com