如何理解NSMutableSet的成员测试和添加竞争条件?
How to understand the member testing and adding race condition of NSMutableSet?
在看《Objective-C 2.0 Phrasebook》这本书的时候,NSMutableSet有一点不太明白,如下,
There is a potential race between testing whether the string is in the
set and adding the new one if it isn’t. A thread-safe version of this
would require you to acquire a lock after the -member:
call, send this
message again, and then finally release the lock after adding the new
object.
我不明白为什么我应该
send this message again
这是否意味着我应该再次拨打 -member:
电话?请帮我。
任何代码示例将不胜感激。
在Objective-C中,像[mySet member:candidate]
这样的表达式将名为member:
的“消息”发送给mySet
(“接收者”),参数为candidate
.它通常被称为“方法调用”或只是“调用”,但 it’s more properly called “sending a message” 或“消息发送”,因为 Objective-C 消息发送中的机制(和定制机会)比在 C++ 或 Java.
等更常见语言的方法调用中
所以是的,当书上说“再次发送这条消息”时,意思是再做一次[mySet member:candidate]
。我没看过这本书,但你的引文描述了“双重检查锁定”模式。
但是,如果您从多个线程访问相同的NSMutableSet
,那么本书所描述的内容不足以避免竞争条件(如果您不需要只能从单个线程访问 NSMutableSet
)。问题是,如果您在线程 A 上说 [mySet addObject:newMember]
,那么从线程 B 同时访问 mySet
是 不安全 。在 [= 执行期间19=] 方法,该集合可能处于内部不一致状态,可能(例如)导致另一个线程上的同时 member:
调用崩溃。除了写入访问之外,您还必须将 读取 访问锁定到 mySet
,因此双重检查锁定模式不足以保护跨线程共享 NSMutableSet
。
处理此问题的最佳方法是使用 dispatch_queue_t
来管理对 NSMutableSet
的独占访问,不要担心任何更复杂的事情,除非探查器告诉您这是一个瓶颈。
在看《Objective-C 2.0 Phrasebook》这本书的时候,NSMutableSet有一点不太明白,如下,
There is a potential race between testing whether the string is in the set and adding the new one if it isn’t. A thread-safe version of this would require you to acquire a lock after the
-member:
call, send this message again, and then finally release the lock after adding the new object.
我不明白为什么我应该
send this message again
这是否意味着我应该再次拨打 -member:
电话?请帮我。
任何代码示例将不胜感激。
在Objective-C中,像[mySet member:candidate]
这样的表达式将名为member:
的“消息”发送给mySet
(“接收者”),参数为candidate
.它通常被称为“方法调用”或只是“调用”,但 it’s more properly called “sending a message” 或“消息发送”,因为 Objective-C 消息发送中的机制(和定制机会)比在 C++ 或 Java.
所以是的,当书上说“再次发送这条消息”时,意思是再做一次[mySet member:candidate]
。我没看过这本书,但你的引文描述了“双重检查锁定”模式。
但是,如果您从多个线程访问相同的NSMutableSet
,那么本书所描述的内容不足以避免竞争条件(如果您不需要只能从单个线程访问 NSMutableSet
)。问题是,如果您在线程 A 上说 [mySet addObject:newMember]
,那么从线程 B 同时访问 mySet
是 不安全 。在 [= 执行期间19=] 方法,该集合可能处于内部不一致状态,可能(例如)导致另一个线程上的同时 member:
调用崩溃。除了写入访问之外,您还必须将 读取 访问锁定到 mySet
,因此双重检查锁定模式不足以保护跨线程共享 NSMutableSet
。
处理此问题的最佳方法是使用 dispatch_queue_t
来管理对 NSMutableSet
的独占访问,不要担心任何更复杂的事情,除非探查器告诉您这是一个瓶颈。