全局配置的最佳实践

Best practice for a global config

本文关键字:最佳 配置 全局      更新时间:2023-10-16

我有几个C 程序,这些程序都在/etc/foo/config.yml中读取YAML配置文件。我编写了一个函数,该函数读取来自文件

的配置
YAML::Node load_config();

(使用yaml-cpp库)。

我希望在程序的main()函数开头加载一次该配置,然后无处不在作为某种全局变量。

当前,我的许多函数都具有额外的参数,它们仅是从配置文件中读取的值。可以通过具有这种全局配置来避免它,使我的功能定义更简单,更可读。

旁注:我还使用OpenMP进行分发计算,这意味着必须在所有并行过程中访问配置。

有人可以给出一个很小的例子,说明做正确的方法时会是什么样?

谢谢!

这是一种方法。这是施瓦茨计数器的想法的一种变体,用于管理全局单例(例如,std::cout本身)

// globals.hpp
#include <istream>
struct globals_object
{
    globals_object()
    {
        // record number of source files which instanciate a globals_object
        ++init_count_;
    }
    ~globals_object()
    {
        // The last source file cleans up at program exit
        if(--init_count_ == 0)
        {
            if (pimpl_)
            {
                delete pimpl_;
            }
        }
    }
    // internal implementation   
    struct impl
    {
        void load(std::istream& is)
        {
            // do loading code here
        }
        int get_param_a() const {
            return a_;
        }
        int a_;
    };
    // (re)load global state    
    void load(std::istream&& is)
    {
        if (pimpl_) delete pimpl_;
        pimpl_ = new impl;
        pimpl_->load(is);
    }
    // public parameter accessor    
    int get_param_a() const {
        return get_impl().get_param_a();
    }
private:    
    static int init_count_;
    static impl* pimpl_;
    static impl& get_impl()
    {
        return *pimpl_;
    }
};
// one of these per translation unit
static globals_object globals;

// globals.cpp
// note - not initialised - will be zero-initialised
// before global constructors are called 
// you need one of these in a cpp file
int globals_object::init_count_;
globals_object::impl* globals_object::pimpl_;

// main file
// #include "globals.hpp"
#include <fstream>
int main()
{
    globals.load(std::ifstream("settings.yml"));
}

// any other file
// #include "globals.hpp"
#include <iostream>
void foo()
{
    std::cout << globals.get_param_a() << std::endl;
}