在C ++中对只读数据进行一次计算后即可共享多个数据

时间:2018-12-07 14:19:54

标签: c++ multithreading c++11 sharepoint

我对多线程编程非常陌生,需要一些有关此问题的指导。

我有这个对象,该对象的计算成本很高,所以我想做的就是仅在需要时计算它,一旦另一个线程需要它,则一旦计算就将其与读取访问权限共享。我只知道在运行时需要哪些输入。

所以我的基本想法是这样的

class ExpansiveDoubleCalc
{
    private:
        static double *ptr[10];
        double DoExpansiveCalc(int input)
        {
            double expansivecalc = (123.4 * input);
            return expansivecalc;
        }

    public:
        ExpansiveDoubleCalc(int input, double* output)
        {
            if(ptr[input]==NULL)
                *ptr[input] = DoExpansiveCalc(input);
            output = ptr[input];
        }

};

double * ExpansiveDoubleCalc::ptr[10]{};

让我们假设我只需要输入<10。 从我对多线程的一点了解来看,这有很多问题: *线程可以尝试同时运行DoExpansiveCalc *一旦获得计算出的指针以输出回去,如果有多个线程尝试访问它,则会变慢

对吗?如何使其安全? 另外,我可能应该在这里返回const指针,对吗?有什么好方法吗?

感谢您的帮助!!干杯!

2 个答案:

答案 0 :(得分:1)

现代cpp中基于规则锁的解决方案:https://gcc.godbolt.org/z/SsQaEB

一些注意事项:

  1. 我正在运行时设置大小。如果您在编译时知道大小,请更改为std::array
  2. 通常不建议使用静态全局状态。使用rawptr或std::shared_ptr明确共享对象。

#include<mutex>
#include<vector>

class ExpensiveDoubleCalc {
    public:
    ExpensiveDoubleCalc(size_t size) : data(size){
    }

    static double DoExpensiveCalc(int input) {
        return 123.4 * input;
    }

    double get(int input) {
        return data.at(input).get(input);
    }

    private:
    struct Data {
        bool isSet{false};
        double val;
        std::mutex m;
        double get(int input){
            std::lock_guard<std::mutex> lock{m};
            if(isSet){
                return val;
            } else {
                val = DoExpensiveCalc(input);
                isSet = true;
                return val;
            }
        }
    };    
    std::vector<Data> data;

};

答案 1 :(得分:0)

因此,最后我使用了Meyers Singleton,它保存着一个数组,该数组存储每个int输入的昂贵计算,仅当数组条目不存在时才进行计算。如果有人感兴趣,我可以整理一个代码示例。