我在写一个Objective-C类,我想要线程安全。要做到这一点,我使用pthreads和pthread_rwlock
(使用@synchronized
是矫枉过正,我想了解更多关于pthreads)。该锁定在指定为init
方法的对象中,并在dealloc
中销毁。我有三种操作锁定的方法; readLock
,writeLock
,unlock
。这三个方法只是简单地调用相关的pthread函数,目前没有其他的东西。如何确定线程是否有锁?
下面是的对象的方法,两者都需要一个writeLock二:
-(void)addValue:(const void *)buffer
{
[self writeLock];
NSUInteger lastIndex = self.lastIndex;
[self setValue:buffer atIndex:(lastIndex == NSNotFound) ? 0 : lastIndex+1];
[self unlock];
}
-(void)setValue:(const void *)buffer atIndex:(NSUInteger)index
{
[self writeLock];
//do work here
[self unlock];
}
setAddValue:
调用将首先获得写入锁定,然后调用setValue:atIndex:
这也将试图获得一个写锁。该文档指出,发生这种情况时行为是不确定的。因此,如何在尝试获取锁之前检查线程是否有锁? (我可以确保临界区不会触发另一个锁请求,但这意味着代码重复,并且我想让我的代码干掉)。
该信息稍微正确。 'EDEADLK'错误只针对'pthread_rwlock_(rd | wr)锁定'指定,而不是trylock函数,在这种情况下它将返回'EBUSY',并且不区分锁定是由调用线程还是其他线程持有。此外,由同一个线程保持的锁只有在写入锁定时才能检测到。由于可以有无限数量的阅读器,所以持有锁的阅读器的身份不能被检查。然而,在OP的情况下,它看起来像一个双重写锁是需要避免的问题,所以它可能是好的。 – 2011-04-23 21:25:05
此外,'EDEADLK'错误只是一个“可能”,而不是“应该”,即不需要执行检测和报告 – 2011-04-23 21:26:45
在进一步的考虑中,我认为您的解决方案不可行。我已经发布了一个替代方案作为答案。 – 2011-04-23 21:32:44