std :: future或std :: shared_future等待多个线程

时间:2016-05-22 11:09:26

标签: c++ c++11 c++14

我有一个线程从容器中获取每个元素并向数据库发送上传请求。上传是同步完成的。

容器中的元素是金融合约,它们可能有也可能没有与之关联的数据结构调用。

现在,对于那些有选票的合同,我必须进行两次上传。 1)首先将ticktable上传到db。 db给出了一个id。 2)将id附加到合同上,然后上传合同。

因此,例如,如果我在具有100个合同的容器上循环,那么可以说其中30个具有ticktable,其余70个没有。

我想弄清楚std::futurestd::shared_future是否适合这样的任务?

我尝试通过将30个合同中的每一个与未来相关联来实现,并使用launch:async policy调用std :: async。因此,在循环的第一遍中,启动了3个线程,并且返回的未来被移动了#39;到与合同相关的容器。 其他70份合约只是以通常的方式上传。

在第二遍中,我希望对存储的未来打电话get()。如果请求已完成,请获取ID并使用它完成合同上载。这可能不会起作用,因为我认为将未来转移到容器将分离线程。

请问您可以建议我采取什么样的方法来实施我想要的行为?

1 个答案:

答案 0 :(得分:0)

移动未来会导致其状态移至目标。所以不,你没有你认为的问题。

您的可选择解决方案看起来像未来的未来 - 可选择上传的一个未来,一个用于合同上传。但是,未来的未来在某种意义上是未来。

因此,一种方法是将未来的未来融入未来。

假设您有一个合约类型Contract(我假设它是伪常规类型)。绑定您的ticktable id是function<void(Contract&)>类型的操作。有趣的是,这样的操作也可以是一个noop。

所以有一个std::future<void(Contract&)> Contract::PrepareForUpload() const。对于您要上传的每份合约,请选择它。

具有可勾选返回值的std::async生成future拥有一个帖子。

没有选票的人返回包含noop std::async工厂的延迟[]{return [](auto&&...){};}

接下来,添加运行准备代码的std::future<void> Contract::Upload(std::function<void(Contract&>) const,然后进行上传(为什么要在此处执行此操作?稍后会显示)。

现在上传的操作是:

auto prep = contract.PrepareForUpload();
auto upload = contract.Upload(prep.get());

现在这有点烦人。做两件事? ICK。

为什么不为我们这样做?

std::future<void> Contract::Upload() const {
  return std::async(
    std::launch::async,
    [this]{
      auto prep = contract.PrepareForUpload();
      return contract.Upload(prep.get());
    }
  );
}

现在Contract::Upload会自动为您准备上传内容。

然而,这可以在可选择的情况下启动2 thrads。所以写一个可以在“撰写的”PrepareForUpload情况下调用的同步Upload

如果PrepareForUpload需要额外的参数,我们可以将它们传递给Upload

你可能还没有提到可能会产生这种诡计的细节,但对未来连锁店的正确答案通常是将链条折叠成一个未来。

C ++ 1z提出了.then和类似功能的建议,以便使这种链式折叠变得简单而有效。