处理多个std :: async调用

时间:2016-03-30 12:00:09

标签: c++ multithreading c++11 asynchronous c++14

我有一个要求,我需要有效删除数千个文件。目前,文件以顺序方式删除。

我想通过使用std :: async()以异步方式调用delete来加速删除。

当前流程:

  1. 获取文件列表
  2. 对于每个文件调用delete()
  3. 所需流程:

    1. 获取文件列表
    2. 对于每个文件:
      1. 使用std :: async()
      2. 调用AsyncDelete()
      3. 将未来对象存储在矢量
    3. 等待每个删除完成,然后返回
    4. 我将使用std::launch::async启动每个异步任务,以便它在单独的线程上运行。

      我有以下问题:

      1. async()是否适合涉及多个任务的工作负载?或者使用线程进行此类任务更好?我在Scott Myer的书" Effective Modern C ++"中读了一章(第35项:首选基于任务的编程到基于线程),他建议使用基于任务的编程而不是线程基

      2. 每个" async()"呼叫?是否有像线程创建开销一样的开销?我计划控制每个周期调用的异步任务的数量。对于例如如果要删除10,000个文件,我将每个周期调用100个删除,而不是一次性生成10,000个async()任务。我希望标准库实现有效地处理多个异步调用(例如使用线程池)。

      3. async()返回的future()对象公开了get()和wait()方法。我读过,get()内部调用wait()。是否足以在存储在向量中的每个期货上调用get()?

      4. 如果get()永远不会返回怎么办?是否建议使用wait_for()并超时?

3 个答案:

答案 0 :(得分:4)

您可能会发现这并不像您希望的那样实际上有所帮助。文件系统可能具有内核级别锁定(以确保一致性),并且有许多线程命中这些锁定可能会导致问题。

我建议

  1. 获取文件列表。
  2. 将列表分成(比方说)十个相等的块(由迭代器对表示)。
  3. 启动十个线程,每个线程删除自己的列表块。
  4. 等待十个主题完成。

  5. 尝试使用不同的十个值。

答案 1 :(得分:1)

作为完全的不同方法,您是否考虑将所有内容移动到数据库中?快速删除成千上万的持久性事物只是数据库擅长的东西。

答案 2 :(得分:1)

瓶颈是I / O操作和操作系统级文件系统操作,委托数千个线程来做这件事不太可能缓解这个瓶颈 - 实际上,你可能会发现这种方法实际上会减慢事情的速度下来。

正如其他人所提到的,根据文件的大小,将数据存储在内部数据库中而不是滥用文件系统可能会更好。

否则,我可能建议使用一个线程删除文件,然后等待(或不等待)线程完成。

回答关于async成本高昂的一个问题:std::async的实现是编译器和操作系统特定的,并且可以与机器上的本机线程实现的开销相媲美。真的,最好的办法就是自己做基准测试。