为什么在多个线程中修改NSMutableSet时崩溃,但是在同一个线程内修改自定义对象Person不会崩溃?


至此
2024-12-19 01:00:05 (2月前)


下面是代码。在街区内我尝试了3箱。只评估一次休息的一个案例。

set = [[NSMutableSet alloc] init];
Person * p = [[Person alloc] init];

dispatch_queue_t queue = …

2 条回复
  1. 0# 妖邪 | 2019-08-31 10-32



    首先,我们要清楚,这些都不是线程安全的。如果您真的要从多个线程执行此操作,则需要进行同步。



    其次,你也应该毫不犹豫地从无法产生特定崩溃中得出结论。众所周知,它们难以表现出来。此外,您正在测试一组非常狭窄的行为,从不测试读取是否成功,返回的对象是否内部一致等。



    关于将一个相同的对象重复添加到一个集合中,这不是一个很好的测试,因为后续的添加无疑会确定该对象已经在集合中,因此实际上没有发生突变。



    使用自定义对象示例,您所做的只是改变单个指针,但从不使用它。而且,无论如何,某些硬件功能将难以表现出任何问题。这并不意味着您不需要同步,而只是表示难以表现出问题。



    此外,像“人”这样的自定义对象的同步通常需要在更高的抽象层次上发生(例如,如果改变一个人的全名,同时读取真的应该等待所有三个属性,第一,中间和姓氏,到完成,否则你可能会在一些不确定的状态下捕获它)。



    最重要的是,如果你要从多个线程访问它们,你真的应该将你的交互与可变集和你的可变人对象同步。





    我建议你调查线程消毒剂(TSAN,给它的朋友)。因此,在Xcode中,转到“编辑器”»“方案”»“编辑方案…”并启用线程清理程序:








    这将帮助您识别来自多个线程的不安全访问。有关更多信息,请参阅

    螺纹消毒剂和静态分析仪

    视频。



    但正如苹果在上述视频中所说,“没有’良性’竞赛这样的事情。”


登录 后才能参与评论