我想在多线程中执行输入消息流的散列,所以我尝试实现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++中的并发性,想提高散列任务的性能。所以这个想法出现在我的脑海中,但不确定它是否会工作。想知道我是否错过了什么。
1条答案
按热度按时间aoyhnmkz1#
问题将不是“一个向量能持有多少个未来”;future(在大多数系统上)只是一个指向内存块的共享指针,内存块中有一些廉价的并发原语。
问题是你正在为每个将来创建一个线程,然后阻止向前的进程直到线程完成。如果你解决了这个问题,那么你的代码就使用了悬空引用。
所以有几点:
1.除非散列数据值得以小块的形式使用,否则
future<vector<HashData>>
会更高效。1.如果你想要一个
vector<future>
,你也会想要一个vector<promise>
,然后创建一个有限数量的线程(或者从你写的池中获得它们)并实现这些承诺。创建无限数量的future,然后创建无限数量的线程来服务这些future,这是一个糟糕的计划。
最后,
std::async
的有趣之处在于它自己返回一个std::future
,当future被销毁时,它会阻塞它创建的线程的完成,这是一个非典型行为,但它可以防止丢失线程的执行轨迹。