c++ 一个系统中一次可以同时存在多少个std::future对象?

bq8i3lrv  于 2023-02-06  发布在  其他
关注(0)|答案(1)|浏览(106)

我想在多线程中执行输入消息流的散列,所以我尝试实现std::vector<std::future<HashData>> futures;,但不确定一个系统中可以同时存在多少未来的对象。

std::vector<std::future<HashData>> futures;
std::vector<std::string> messages;

for (int i = 0; i < messages.size(); i++)
{
  std::promise<HashData> promiseHashData;
  std::future<HashData> futureHashData = promiseHashData.get_future();
  futures.emplace_back(std::move(futureHashData));
  std::async(std::launch::async, [&]() {PerformHash(std::move(promiseHashData), messages[i]);});
}

std::vector<HashData> vectorOfHashData;
// wait for  all async tasks to complete
for (auto& futureObj : futures)
{
  vectorOfHashData.push_back(futureObj.get());
}

在系统中创建未来对象是否有任何限制(类似于系统如何达到线程饱和水平,如果现有线程不会被破坏,新线程会不断创建),因为我将以异步方式调用PerformHash()方法,用于大型消息数据。
我最近在探索c++中的并发性,想提高散列任务的性能。所以这个想法出现在我的脑海中,但不确定它是否会工作。想知道我是否错过了什么。

aoyhnmkz

aoyhnmkz1#

问题将不是“一个向量能持有多少个未来”;future(在大多数系统上)只是一个指向内存块的共享指针,内存块中有一些廉价的并发原语。
问题是你正在为每个将来创建一个线程,然后阻止向前的进程直到线程完成。如果你解决了这个问题,那么你的代码就使用了悬空引用。

std::vector<std::future<HashData>> futures;
std::vector<std::string> messages;

for (int i = 0; i < messages.size(); i++)
{
  std::promise<HashData> promiseHashData;
  std::future<HashData> futureHashData = promiseHashData.get_future();
  futures.emplace_back(std::move(futureHashData));
  // this captures a promiseHashData by reference
  // It also creates a thread, then blocks until the
  // thread finishes.
  std::async(std::launch::async, [&]() {PerformHash(std::move(promiseHashData), messages[i]);});
}

所以有几点:
1.除非散列数据值得以小块的形式使用,否则future<vector<HashData>>会更高效。
1.如果你想要一个vector<future>,你也会想要一个vector<promise>,然后创建一个有限数量的线程(或者从你写的池中获得它们)并实现这些承诺。
创建无限数量的future,然后创建无限数量的线程来服务这些future,这是一个糟糕的计划。
最后,std::async的有趣之处在于它自己返回一个std::future,当future被销毁时,它会阻塞它创建的线程的完成,这是一个非典型行为,但它可以防止丢失线程的执行轨迹。

相关问题