【问题标题】:How do I check if an object is being @synchronized如何检查对象是否正在@synchronized
【发布时间】:2013-07-01 03:10:05
【问题描述】:

有时我会编写以下代码来同步例程:

@synchronized(objToBeSync){ .... }

当两个线程试图同时访问同步块时,一个会阻塞另一个,直到一个退出同步块。

但是,有时我不希望一个阻止另一个,但其他人检查对象是否正在同步,然后做一些其他事情,所以我必须这样做:

@synchronized(objToBeSync){
    _isBeingSync = YES;
    ... 
    _isBeingSync = NO;
}

_isBeingSync 是检查 objToBeSync 是否正在同步的附加变量。其他线程在继续工作之前检查_isBeingSync。我的问题是,objc 是否提供了直接检查 objToBeSync 的功能,但没有引入额外的 var 来标记其状态。

【问题讨论】:

    标签: objective-c locking nonblocking synchronized


    【解决方案1】:

    编译器将@synchronized(objToBeSync) { ... } 翻译成

    callq   _objc_sync_enter
    ...
    callq   _objc_sync_exit
    

    并且从 Objective-C Runtime Source Code(objc-sync.mm, objc-os.mm, objc-lockdebug.mm, objc-os.h) 一看就知道这几个函数主要做了一个

    pthread_mutex_lock(m->mutex);
    ...
    pthread_mutex_unlock(m->mutex);
    

    其中m->mutex 是带有PTHREAD_MUTEX_RECURSIVE 属性的pthread_mutex_t 与对象 objToBeSync 相关联,使用运行时内部的缓存。

    因此,您的问题的直接答案是:不,没有公共 API 可以获取 对象的“锁定”状态,而访问内部互斥锁对我来说几乎是不可能的。

    因此,如果您有此要求,您应该使用不同的锁定机制, 例如Posix 互斥锁,NSLockNSRecursiveLock。所有这些锁都有一个 "try" 方法,可用于获取锁,或立即失败而不阻塞。

    "Threading Programming Guide: Synchronization" 了解概览。

    请注意,@synchronized(与其他锁定机制相比)隐式地向块添加异常处理程序,以便 如果抛出异常,则释放互斥锁。

    另外@synchronized是一个递归锁,即同一个线程可以进入受保护的 代码没有阻塞。如果这与您的代码相关,您将不得不使用 NSRecursiveLock 或具有“递归”属性的 Posix 互斥锁。

    请注意,为此目的使用简单的实例变量_isBeingSync 是主题 竞争条件,将无法安全工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 2011-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多