【发布时间】:2020-07-20 18:43:42
【问题描述】:
我需要执行一些计算,这取决于两个或多个步骤,如下所示:
class A
{
public:
double step1() { return 2.5; }
};
class B
{
public:
double step2() { return 1.2; }
};
class Result
{
public:
Result(std::shared_ptr<A> _a, std::shared_ptr<B> _b) : a(_a), b(_b) {};
double getResult() { return a->step1() + b->step2(); }
private:
std::shared_ptr<A> a;
std::shared_ptr<B> b;
};
实际上,第 1 步和第 2 步需要多态行为,因此这些(共享)指针将指向“接口”类,但这里的细节并不重要。
现在,getResult() 中的最终计算也需要多态行为,因此我创建了一个指向 Result 的(唯一)指针,创建了一个调用 getResult() 的 lambda,并将该 lambda 传递给我的线程,如下所示:
void run_multi_threaded_calculation()
{
auto result = create_result_unique_ptr();
const int nThreads = 4;
std::vector<double> save(nThreads);
auto task = [&](int n) {
// Preprocessing before getResult()
save[n] = n * result->getResult();
};
std::vector<std::thread> threads;
threads.reserve(nThreads);
for (size_t i = 0; i < nThreads; ++i)
{
threads.push_back(std::thread(task, i));
}
for (auto& th : threads)
th.join();
for (const auto& s : save)
std::cout << s << '\n';
}
问题 1: 我是否使用了正确的智能指针和 lambda 捕获配置,例如unique_ptr 到 Result 和 shared_ptr 到 A 和 B?经过一些猜测并检查更改智能指针类型后,上述编译(但如果Result 中的a 和b 是unique_ptr,则不会编译),但我不确定这是否是最好的方法接近这个。
问题 2: 如果我将 lambda 替换为等效的(或者我认为的)函数对象,那么我的代码无法编译(错误 C2661: 'std::tuple
以下是相关更改:
class ResultFunctor
{
public:
ResultFunctor(std::unique_ptr<Result> _result, std::vector<double>& _save) : result(std::move(_result)), save(_save) {};
void operator() (int n) { save[n] = n * result->getResult(); }
private:
std::unique_ptr<Result> result;
std::vector<double>& save;
};
并替换以下行:
void run_multi_threaded_calculation()
{
// Other stuff is unchaged...
/*auto task = [&](int n) {
// Preprocessing before getResult()
save[n] = n * result->getResult();
};*/
auto task = ResultFunctor(std::move(result), save);
// other stuff is unchanged...
}
【问题讨论】:
-
为什么
result必须是指针? -
这只是演示我的问题的最简单的例子。我的实际程序将具有
Result的多态行为,派生自IResult基类之类的东西。然后getResult将使用第 1 步和第 2 步,但会进行一些其他不同的计算。 -
这可能是协程的一个很好的用例,尤其是在步骤的顺序很重要的情况下。在您的示例中,我认为您不能确定 step1 会在 step2 之前进行评估。
-
我会研究协程,但你的评论让我意识到我的例子有点误导。实际上,这些步骤不会在同一行中进行评估,而更像是:
step1() /*... Do some stuff with the result...*/ step2()。
标签: c++ multithreading lambda smart-pointers function-object