我对多线程编程非常陌生,需要一些有关此问题的指导。
我有这个对象,该对象的计算成本很高,所以我想做的就是仅在需要时计算它,一旦另一个线程需要它,则一旦计算就将其与读取访问权限共享。我只知道在运行时需要哪些输入。
所以我的基本想法是这样的
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指针,对吗?有什么好方法吗?
感谢您的帮助!!干杯!
答案 0 :(得分:1)
现代cpp中基于规则锁的解决方案:https://gcc.godbolt.org/z/SsQaEB
一些注意事项:
std::array
。 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输入的昂贵计算,仅当数组条目不存在时才进行计算。如果有人感兴趣,我可以整理一个代码示例。