Objective c 没有正确使用NSLock,但似乎仍然有效
我有线程安全问题。我有一个队列,当我修改内容时,它会导致线程间的错误。我以前没用过锁,但我想试试。我在操纵队列的备用NSMutableArray的所有代码周围添加了一个锁。我想问题是,我没有对所有的锁使用相同的锁。我在修改数组的每个方法中创建了一个新的NSLock实例。我假设我应该使用一个NSLock ivar来保护阵列。但我的困惑来自这样一个事实:一旦我添加了它,它就起作用了。下面是一个例子。我假设在创建新NSLock的任何地方,我都应该使用一个ivar NSLock。我认为这段代码只是锁定了排队与其他排队的关系,以及排队与其他排队的关系,而不是排队与其他排队的关系。澄清一下就好了Objective c 没有正确使用NSLock,但似乎仍然有效,objective-c,cocoa,thread-safety,nslock,Objective C,Cocoa,Thread Safety,Nslock,我有线程安全问题。我有一个队列,当我修改内容时,它会导致线程间的错误。我以前没用过锁,但我想试试。我在操纵队列的备用NSMutableArray的所有代码周围添加了一个锁。我想问题是,我没有对所有的锁使用相同的锁。我在修改数组的每个方法中创建了一个新的NSLock实例。我假设我应该使用一个NSLock ivar来保护阵列。但我的困惑来自这样一个事实:一旦我添加了它,它就起作用了。下面是一个例子。我假设在创建新NSLock的任何地方,我都应该使用一个ivar NSLock。我认为这段代码只是锁定了
@implmentation
...
- (void)enqueue:(id)obj
{
NSLock *arrayLock = [[NSLock alloc] init];
[arrayLock lock];
[_backingStore addObject:obj];
[arrayLock unlock];
}
- (id)dequeue
{
NSLock *arrayLock = [[NSLock alloc] init];
[arrayLock lock];
id result = [_backingStore firstObject];
if( result )
{
[_backingStore removeObjectAtIndex:0];
}
[arrayLock unlock];
return result;
}
...
@end
是的,您确实需要使用相同的NSLock实例来锁定对阵列的两次访问。与如此多的多线程错误一样,由于添加额外代码导致的时间差异,问题似乎已经消失。或者,可能只是你运气不好,第二次测试时问题没有出现 不管它值多少钱,NSLock只是锁定对Objective-C中关键部分访问的一种方式。您还可以使用
@synchronized()
,从代码复杂性的角度来看,这可能更容易:
@synchronized(someSharedToken) {
// Do your array access here
}
您还可以使用串行调度队列来序列化对资源的访问。这有几个优点,其中最重要的一个是能够向它分派工作,而无需等待该工作在当前线程上完成。将工作分派到队列也比取出锁便宜。请参阅Apple的并发编程指南。谢谢您的回答。我计划转到调度队列。我曾想过使用@synchronized,但认为它会为异常处理带来额外的开销。由于必须使用同一个实例,这是否意味着在我的示例中,如果两个线程调用enqueue方法,两个线程都不会实际阻止另一个,因为每个方法调用都会创建自己的实例?是的。我在这里举了一个又快又脏的例子,你可以看到这一点:。谢谢你的例子。