2009-10-17 45 views
1

我应该在应用程序委托中制作一个NSLock实例,供所有类使用吗?或者建议每个类根据需要实例化自己的NSLock实例?应该是一个NSLock实例“全球”?

如果我在第二种情况下锁定工作,例如,是否可以访问分布在两个视图控制器上的托管对象上下文?

+0

使用手工编码的锁时非常害怕,并且怀疑对它们的需求。 – 2009-10-18 10:41:42

+2

我不确定这是什么意思。如果使用线程,核心数据指南建议锁定对托管对象上下文的访问。除了手动编码的'NSLock'锁定 - 解锁对之外,我还会使用什么? – 2009-10-18 10:54:29

+0

是的,我只是说,小心......在这种情况下,这是适当的。 – 2009-10-18 20:57:12

回答

3

如果多个对象只访问您的对象来读取其内容,那么您根本不需要锁。如果至少有一个对象访问您的对象以写入/更新其内容,则其他对象是否访问您的对象来读取或写入/更新对象并不重要:在这种情况下,您需要锁定。

现在,为了正确地保护您的对象(在多个对象可以访问它的代码的关键部分),您必须使用SAME LOCK INSTANCE,然后必须由所有访问该对象的可能对象共享愿意保护。

如果您的应用程序需要保护可能被大多数类同时访问的对象,那么拥有单个锁实例就没有问题。如果你想要更好的表现(尤其是如果你的对象同时访问的数量很高),那么你可以有多个锁。每个锁将负责允许/拒绝访问对象的特定属性/字段。这样,几个对象可以同时访问您的对象来更改不同的属性/字段。你基本上增加了你的对象的并发操作的数量。但是,每个锁都必须在将访问您保护的对象的其他对象之间共享。

每个控制器都有一个锁定实例根本不起作用;这不会保护您的对象免受来自不同线程中其他对象的并发访问。 NSLock是使用POSIX pthread互斥体实现的,因此它必须以完全相同的方式使用。这在NSLock文档中也有明确说明:

警告:NSLock类使用POSIX线程来实现其锁定行为。向NSLock对象发送解锁消息时,必须确保该消息是从发送初始锁定消息的同一线程发送的。解锁来自不同线程的锁可能导致未定义的行为。

因此,为了保留临界区语义,它是获取负责完成释放它的锁的同一个线程。还要注意的是,锁定机构仅用于快速操作,即在释放它之前您应该只在很短的时间内获得锁定。如果您需要等待不可预知的时间,那么您需要一个不同的同步机制,即通过NSCondition类可用的条件变量。

希望这会有所帮助。

+1

从文档中明显可以看出,用于锁定特定线程的同一个锁也可用于解锁。然而,从'NSLock'的文档中并不清楚所有类都必须使用同一个锁实例。我也在阅读,如果我多次使用'[myLock lock]',在发出相应的[[myLock unlock]]之前,该线程将冻结。所以我仍然不确定是否需要将'myLock'的实例化和范围限制到被调用的特定类/线程,或者我是否可以毫无问题地使用应用程序范围的'myLock'。 – 2009-10-18 10:52:39

+0

我建议阅读posix pthread mutexes的文档。你会看到一个互斥锁(一个NSLock)必须在所有访问你要保护的对象的线程之间共享。请注意,我并不是说它必须在所有线程中全局共享,只有这些线程才能访问您的对象。你说连续两次锁定是正确的:除非互斥量递归,否则会出现问题。要使用递归互斥锁,你必须使用一个NSRecursiveLock对象。请参阅“线程编程指南”文档,特别是“同步”部分。 – 2009-10-18 18:57:11

1

您不应该对核心数据使用锁。该文档可能已过时。理想情况下,每个线程应该有一个上下文,并让上下文处理其基础NSPersistentStoreCoordinator的锁定。这被认为是当前在多线程应用程序中使用核心数据的安全方式。

相关问题