【问题标题】:Concurrent file enumeration并发文件枚举
【发布时间】:2013-10-19 17:31:08
【问题描述】:

我必须对大量文件执行复杂的操作。幸运的是,枚举顺序并不重要,作业可以并行完成而无需锁定。

平台是否提供了执行此操作的方法?由于缺乏更好的 API,我在考虑:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSArray *paths = [[NSFileManager defaultManager] subpathsAtPath:folder];
    [paths enumerateObjectsWithOptions:NSEnumerationConcurrent 
    usingBlock:^(NSString *path, NSUInteger idx, BOOL *stop) {
        // Complex operation
    }];
}];

有没有更好的办法?

【问题讨论】:

  • 我就是这么写的,也很想知道有没有更好的办法。
  • 你在寻找多少并发。您的代码将在后台运行,但不会同时运行多个文件操作。你也不应该在后台线程上使用defaultManager
  • @Wain 您能否详细说明原因(也许在答案中)?我有兴趣使用尽可能多的内核来并行处理文件。

标签: ios objective-c macos concurrency nsfilemanager


【解决方案1】:

您当前的代码将一个块放在全局队列中。因此,该单个块将在后台线程上运行并执行所有迭代和处理。

您想要做一些不同的事情来让您的处理任务同时运行。您真的应该在主线程上进行迭代,并在循环的每次迭代中向全局队列添加一个块。

更好的是,创建一个NSOperation 子类。把你的逻辑放在那里。在循环中创建操作的实例并将它们添加到操作队列中。这是一个更高级别的 API,并为您提供添加依赖项、定制最大并发性、检查仍待完成的操作数量等方面的选项...

【讨论】:

    【解决方案2】:

    这是您可以考虑的一种方法。如果您有(或可能有)数万个文件,而不是使用enumerateObjectsWithOptions:usingBlock: 枚举,您可能希望批量手动枚举数组(假设每个 100 个元素)。当当前批次完成执行时(您可以使用调度组来检查),您开始下一个批次。使用这种方法,您可以避免向队列中添加数以万计的块。

    顺便说一句,我已经删除了我之前的答案,因为它是错误的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-30
      相关资源
      最近更新 更多