如何在 C++ 中将数据初始化保护到一个线程

问题描述 投票:0回答:3

使用现代 C++ 获得一些由一个线程初始化的共享内存的最佳方法是什么,第一个到达这一点,然后由多个线程读取。它需要尽可能轻巧。

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();
}

如果有帮助,我真的想避免将代码的整个读取部分包装在互斥锁中。

PS:这不是静态函数变量的用例,因为我将在程序运行中创建其中的许多变量。

c++ mutex c++20 atomic stdatomic
3个回答
3
投票

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
的初始化值。


0
投票

正如我评论的那样,使

ptr
成为局部静态变量。

int* get_ptr() {
  static int *ptr = init_ptr();
  return ptr;
}

void parallel_work() {
  // all threads read After ptr is set 
  do_with(get_ptr());
}

-2
投票

Scott Mayer 的单例就可以了。只需将 statc 对象放入函数中:

result_t& single (){
    static result_t res{ /*initialization parameters*/};
    return res;
};

编译器通过隐藏的

once_flag
对象或类似的魔法管理第一次调用ownin函数的初始化。

© www.soinside.com 2019 - 2024. All rights reserved.