【问题标题】:NSMutableString thread safety?NSMutableString 线程安全?
【发布时间】:2013-04-28 11:19:46
【问题描述】:

我有一个很大的 NSMutableString(可能有数百兆字节),需要对其执行大量 rangeOfCharacterFromSet: 操作。

为了提高性能,我希望有一个 NSOperationQueue 将字符串拆分为约 100kb 的块并异步处理每个块。

但由于字符串太大,为每个线程制作不可变副本是不可行的。

假设我不允许修改字符串(我打算阻塞主线程直到操作队列完成),这样安全吗?

Apple 将 NSString 记录为线程安全,所有不可变对象“通常”不是线程安全的,但大概只适用于某些方法? rangeOfCharacterFromSet 是我唯一使用的。

此代码将在 OS X 和 iOS 上运行(通常在 iOS 上使用较小的字符串)

【问题讨论】:

  • 为什么每个线程都有原始 NSString 的单独“副本”?如果不允许修改字符串,为什么还要使用 NSMutableString?
  • 为什么要阻塞主线程?如果您要这样做,那么线程的目的是什么?
  • 我还有一个问题:您是否真的测试过性能,还是只是猜测?您知道存在需要拆分字符串的性能问题吗?
  • matt:在这种情况下,大概 Abhi 是在并发,而不是异步之后
  • 这是dispatch_apply的工作吗?

标签: objective-c multithreading thread-safety


【解决方案1】:

虽然我怀疑 NSMutableString(或至少其常见实现)对此是安全的,但最安全的答案可能是创建一个不可变副本,然后对其执行所有操作。

我的谨慎是因为非常大的 NSMutableStrings 可能在内部实现为树,如果该树在读取时进行延迟重新平衡,则可能存在线程安全问题。

【讨论】:

  • 我希望我的应用能够打开尽可能大的文件(即使这可能意味着用户必须等待几秒钟才能开始打开文件),创建副本会使我的应用翻倍内存消耗,所以我真的想避免它。我必须做一些更复杂的事情,比如制作前 50MB 数据的不可变副本,同时处理它,然后制作下一个 50MB 的不可变副本......呃。
  • 这涉及“依赖实现细节的骇人听闻”的东西,但如果你不愿意依赖“它可能没问题”(我完全理解),那么你可以做类似的事情-rangeOfString:串行尝试触发任何可能的惰性状态更改,然后同时触发其余的。
  • 您是否需要将文件一次性加载到内存中?为什么不考虑mmap 之类的?
  • @dreamlax mmap 会给我该文件的只读副本。在用户选择这样做之前,我需要一个读写副本而不向磁盘写入任何内容。对于某些事情,即使它在 RAM 中,我也会遇到性能问题,因此将其存储在磁盘上根本不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
  • 2021-07-12
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
相关资源
最近更新 更多