英文:
How to guard the initialization of data to one thread?
问题
使用现代C++,在一个线程初始化共享内存,然后被多个线程读取的最佳方式是什么?它需要尽可能轻量化。
int *ptr = nullptr;
void parallel_work() {
// 这应该只由第一个到达这一点的线程执行
ptr = init_ptr();
// 在ptr设置之后,所有线程都可以进行读取
do_with(ptr);
}
int main() {
std::thread th0 { ¶llel_work };
std::thread th1 { ¶llel_work };
std::thread th2 { ¶llel_work };
parallel_work();
}
如果可能的话,我真的想避免在代码的整个读取部分包装一个mutex
。
附注:这不是使用static
函数变量的用例,因为我将在程序的生命周期中创建许多这样的变量。
英文:
Using modern C++, what is the best way to have some shared memory that is initialized by one thread, the first to get to this point, and then read by many threads? It needs to be as lightweight as possible.
int *ptr = nullptr;
void parallel_work() {
// this should only done by the first thread to this point
ptr = init_ptr();
// all threads read After ptr is set
do_with(ptr);
}
int main() {
std::thread th0 { &parallel_work };
std::thread th1 { &parallel_work };
std::thread th2 { &parallel_work };
parallel_work();
}
If it can help, I really want to avoid wrapping the whole read part of the code in a mutex
.
PS: this is not the use case for static
function variables, as I'll be creating many of these in the program's lifetime.
答案1
得分: 8
std::call_once
的作用如下。
int *ptr = nullptr;
std::once_flag flag;
void parallel_work() {
std::call_once(&flag, []() {
ptr = init_ptr();
});
do_with(ptr);
}
它甚至会强制其他线程等待,直到 init_ptr
完成,并确保它们都看到 ptr
的已初始化值。
英文:
std::call_once
does exactly this.
int *ptr = nullptr;
std::once_flag flag;
void parallel_work() {
std::call_once(&flag, []() {
ptr = init_ptr();
});
do_with(ptr);
}
It even forces other threads to wait until init_ptr
is done and it synchronizes to make sure they all see the initialized value of ptr
.
答案2
得分: 0
将 ptr
变成一个本地静态变量。
int* get_ptr() {
static int *ptr = init_ptr();
return ptr;
}
void parallel_work() {
// 所有线程在 ptr 被设置之后读取
do_with(get_ptr());
}
英文:
As I commented, make ptr
a local static variable.
int* get_ptr() {
static int *ptr = init_ptr();
return ptr;
}
void parallel_work() {
// all threads read After ptr is set
do_with(get_ptr());
}
</details>
# 答案3
**得分**: -1
Scott Mayer的单例会做。只需将静态对象放在一个函数内:
```C++
result_t& single () {
static result_t res{ /*初始化参数*/ };
return res;
};
编译器通过隐藏的once_flag
对象或类似的魔术,在第一次调用ownin
函数时管理初始化。
英文:
Scott Mayer's singleton will do. Just put the statc object inside a function:
result_t& single (){
static result_t res{ /*initialization parameters*/};
return res;
};
Compiler manages the initialization on 1st call of the ownin function, via a hidden once_flag
object or similar magic.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论