目标 C语言 如何确定线程是否有锁



我正在编写一个Objective-C类,我希望它是线程安全的。为此,我正在使用 pthreads 和 pthread_rwlock(使用 @synchronized 是矫枉过正的,我想更多地了解 pthreads(。锁在方法指定的对象init启动,并在dealloc中销毁。我有三种操纵锁的方法; readLockwriteLockunlock。这三个方法只是调用相关的 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:这也将尝试获取写锁定。文档指出,发生这种情况时的行为是未定义的。因此,在尝试获取锁之前,如何检查线程是否具有锁?

(我可以确保关键部分不会进行触发另一个锁定请求的调用,但这意味着代码重复,我想保持我的代码干燥(。

不完全清楚您使用的锁类型。您指出您正在使用线程和读/写锁定,所以我得出结论,您使用的是pthread_rwlock。

如果这是真的,那么您应该能够在锁上使用pthread_rwlock_trywrlock。 从手册页,

如果成功,则 pthread_rwlock_wrlock(( 和 pthread_rwlock_trywrlock((函数将返回零。 否则,将返回错误号以指示错误。

而且,其中一个错误是:

[埃迪尔克] 调用线程已拥有读/写锁 (用于阅读或写作(。

因此,我相信你应该能够调用pthread_rwlock_trywrlock()并且你会成功,如果另一个线程有锁,它会返回EBUSY,或者如果当前线程有锁,你会得到EDEADLK

首先,仅包含一个操作的关键部分是无用的。关键是要同步彼此相对的不同事物。(您确实有效地使整数原子化,但这可能不是全部意图。

其次,您已经知道在后一个关键部分中有写锁定,因此无需检查它是否存在。 只是不要在写入时尝试读锁定。

解决方案可能是将readLockwriteLock调用移动到调用函数中,但不知道更多就不可能说。

(这也可能会通过减少总操作数来降低锁定的性能成本,因为您不会锁定然后立即解锁。可能您不需要直接在 pthreads 级别工作。

可移植程序不能依赖实现来告诉调用方它已经持有写锁。相反,您需要执行类似操作以使用递归写锁包装 rwlock:

int wrlock_wrap(pthread_rwlock_t *l, int *cnt)
{
    int r = *cnt ? 0 : pthread_rwlock_wrlocK(l);
    if (!r) ++*cnt;
    return r;
}
int wrunlock_wrap(pthread_rwlock_t *l, int *cnt)
{
    --*cnt;
    return pthread_rwlock_unlock(l);
}

您可以将计数保留在pthread_rwlock_t旁边,无论它存储在何处,例如作为结构/类/其他内容的成员。

相关内容

  • 没有找到相关文章

最新更新