gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 13:16:54 25 4
gpt4 key购买 nike

下面是代码。在街区里,我尝试了3种情况。一次只休息一个案例。

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

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
for (int index = 0; index < 100; index++) {
dispatch_async(queue, ^{

//Case 1: adding constant value each time
//[self->set addObject:@"0"];

//Case 2: adding new value on each call.
[self->set addObject:[NSNumber numberWithInt:index]];

//Case 3: Modifying custom object
// p.firstname = [NSString stringWithFormat:@"%d", index];
});

}

我知道如果我在块内放入锁/@ syncronize可以正常工作。

问题1 :为什么即使我尝试使用0到100000的索引范围,情况一仍然运行没有问题。可变集不是线程安全的,因此它一定会崩溃。那么为什么它不同步就可以工作呢?

问题2 :由于情况1每次都运行良好,因此情况2也应运行良好,因为正在修改同一集合。但是每次运行都会崩溃。

问题3 :情况3不会崩溃,即使我每次都以新情况输入新值,以防万一。

注意:所有属性均为非原子性。

案例2崩溃日志:
**malloc: *** **error for object 0x6000028e9260: pointer being freed was not allocated****

最佳答案

首先,我们要弄清楚,这些都不是线程安全的。如果您确实要从多个线程进行同步,则需要进行同步。

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

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

在您的自定义对象示例中,您要做的就是更改单个指针,但从不使用它。加上某些硬件功能将使无论如何都很难表现出任何问题。这并不意味着您不需要同步,而只是要表明问题非常困难。

此外,自定义对象(如“人”)的同步通常需要在更高的抽象级别上进行(例如,如果更改人的全名,那么同时读取实际上应该等待所有三个属性(名,中间名和姓氏)完成,否则您可能会陷入不确定状态)。

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

我建议您研究一下线程 sanitizer (TSAN,送给它的 friend )。因此,在Xcode中,转到“编辑器”»“方案”»“编辑方案...”,然后打开线程清理器:

enter image description here

这将帮助您识别来自多个线程的不安全访问。有关更多信息,请参见Thread Sanitizer and Static Analyzer视频。

但是正如苹果在上述视频中建议的那样,“没有“良性”竞赛。”

关于objective-c - 为什么在多个线程内修改NSMutableSet时崩溃,但是在同一线程内修改自定义对象Person却不会崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55088872/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com