有没有一种方法可以检查 NSLock 是否已被获取?

3

我正在处理多线程代码。数据访问通过“NSLock”对象在几个部分上进行锁定。我希望确保在这些部分内调用的某些方法检查它们适当的锁是否已被获取。

类似于:

assert([myLock isSet] == YES);

我在NSLock中找不到类似于"isSet"的东西。有什么想法可以确保锁已经设置了吗?

谢谢!

2个回答

13

你是如何获取锁的?如果你是通过调用 lock 来获取锁的,那么你能够继续执行代码应该就保证你已经获得了锁。如果你是通过调用 lockBeforeDate 来获取锁的,那么返回值会告诉你是否成功获取。

如果你想从其他地方测试,可以尝试

if ( [myLock tryLock] )
{
    // oops, lock was not previously acquired!
    ...
    [myLock unlock];
}
else
{
    // yep, lock was already acquired
}

然而,总的来说这似乎是一个值得商榷的想法。你应该在需要锁定的地方进行锁定,并相信它能够正常工作,而不是试图从外部监督它。


谢谢。tryLock正是我想要的。 我可以这样做:assert(![myLock tryLock]);我理解这告诉我对象被“锁定”。它并没有告诉我正确的线程是否拥有锁。此外,我同意您这样做是有问题的。但我正在拼命寻找一个错误(我不认为这个错误与锁有关,但我在其他代码中也找不到任何错误 - 所以我必须检查锁定)。 - Lars Schneider
7
tryLock 函数的作用就是尝试去锁定一个锁。如果它可以成功锁定,那不仅意味着在此之前该锁没有被锁定过,而且还意味着现在已经被锁定了。所以,如果 tryLock 成功了,你需要对其进行解锁操作,否则当你可能不希望持有锁时,你就一直在持有这个锁。 - Peter Hosey
3
+1 是对在提问之前回答问题的人的肯定。 - Chris Hatton

6

不行。

因为你看,无论你得到什么结果都是没有用的,因为在你真正使用它之前,它可能()出现错误。 例如:

  1. 你发现锁被锁上了。
  2. 保持锁的线程将其解锁。
  3. 你报告说锁被锁上了。

它也会失败:

  1. 你发现锁没有被锁上。
  2. 另一个线程锁定了锁。
  3. 你报告说锁已解锁。

这就是为什么调试死锁和竞态条件如此棘手的问题所在。

我认为你应该问另一个关于你实际问题的问题。


1
大部分是正确的,但有一个特殊情况。如果锁的获取和测试发生在@synchronized块内部,则应该能够依赖于锁的状态不会改变。 - Chuck Wolber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接