处理多个std::异步调用
Handling multiple std::async calls
我有一个需求,需要高效地删除数千个文件。目前,文件是按顺序删除的。
我想通过使用std::async()以异步方式调用delete来加快删除速度。
电流:
- 获取文件列表
- 对于每个文件,调用delete()
所需流量:
- 获取文件列表
- 对于每个文件:
- 使用std::async()调用AsyncDelete()
- 将未来对象存储在矢量中
- 等待每个删除操作完成,然后返回
我将使用std::launch::async
启动每个异步任务,以便它在单独的线程上运行。
我有以下问题:
-
async()是否适用于涉及多个任务的工作负载?还是将线程用于此类任务更好?我读了Scott Myer的书《高效的现代C++》中的一章(第35项:更喜欢基于任务的编程而不是基于线程的编程),他在书中建议使用基于任务的程序设计而不是基于螺纹的程序设计。
-
每个"async()"调用的成本有多高?它是否有类似于线程创建开销的开销?我计划控制每个周期调用的异步任务的数量。例如,如果要删除10000个文件,我将在每个周期只调用100个删除,而不是一次性生成10000个异步()任务。我希望标准库实现能够有效地处理多个异步调用(例如使用线程池)。
-
async()返回的future()对象公开了get()和wait()方法。我读到过,get()在内部调用wait()。对存储在向量中的每个期货调用get()就足够了吗?
-
如果一个get()永远不会返回怎么办?建议在超时的情况下使用wait_forr()吗?
您可能会发现这实际上并没有您想要的那么多帮助。文件系统可能有内核级别的锁(以确保一致性),如果有许多线程碰到这些锁,可能会造成麻烦。
我建议
- 获取文件列表
- 将列表分成(比如)十个相等的块(由迭代器对表示)
- 启动十个线程,每个线程删除列表中自己的块
-
等待十根线完成。
-
用10的不同值进行实验。
作为一种完全不同的方法,您是否考虑过将所有内容移动到数据库中?快速删除数千个持久的东西正是数据库擅长的。
瓶颈是I/O操作和操作系统级别的文件系统操作,委派数千个线程来做这件事不太可能缓解瓶颈——事实上,你可能会发现这种方法实际上会减慢速度。
正如其他人所提到的,根据文件的大小,最好将数据存储在内部数据库中,而不是滥用文件系统。
否则,我可能建议使用一个线程来删除文件,然后您可以等待(或不等待)线程完成。
要回答您关于async
的成本有多高的一个问题:std::async
的实现是编译器和操作系统特定的,与您机器上的本机线程实现的开销相当。实际上,最好的做法是自己进行基准测试。
- 如何在 c++ 中异步调用静态方法?
- 在 NodeJS 异步调用C++ DLL
- Qt异步调用:如何在异步调用完成任务后运行一些东西
- 重构后,异步调用方法不再有效
- 通过谷歌测试测试异步调用
- 如何使用从Swift代码中调用的线程在C 上制作异步调用功能
- 如何从 dart 对用 C/C++ 编写的函数进行异步调用
- 异步调用槽,而不使用清晰的代码行连接到它
- 修复此标准::异步调用
- V8 JavaScript 如何进行异步调用
- 进行异步调用 - 我必须创建自己的p/s吗?
- C++异步调用最佳实践
- 处理多个std::异步调用
- JNI:C++是否异步调用Java
- 使用 Emscripten 异步调用 JavaScript C++函数
- 如何在 Kernal32.dll 中异步调用 ReadFile()?C#.
- 使用JNI异步调用Java方法
- C++:如何异步调用同步库调用
- 对ReadFile函数的异步调用返回6个错误代码
- 在c++中异步调用CreateFile和ReadFile