有时,我编写了以下代码来同步例程:
@synchronized(objToBeSync){ .... }
当两个线程尝试同时访问同步块(synchronized block)时,一个线程将阻塞其他线程,直到一个线程退出同步块(synchronized block)。
但是,有时我不希望一个阻止另一个,而另一个阻止其他对象检查对象是否正在同步,然后再执行其他操作,因此我必须执行以下操作:
@synchronized(objToBeSync){
_isBeingSync = YES;
...
_isBeingSync = NO;
}
_isBeingSync
是检查objToBeSync是否正在同步的附加变量。其他线程在继续工作之前会检查_isBeingSync
。我的问题是objc是否提供了某种直接检查objToBeSync的东西,但没有引入额外的var来标记其状态。 最佳答案
编译器将@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_t
属性的PTHREAD_MUTEX_RECURSIVE
使用运行时内部的缓存与对象objToBeSync
关联。因此,您问题的直接答案是:不,没有公共(public)API可以获取
对我来说,“锁定”对象的状态以及访问内部互斥锁几乎是不可能的。
因此,如果您有此要求,则应使用其他锁定机制,
例如Posix互斥锁,
NSLock
或NSRecursiveLock
。所有这些锁都有一个可用于获取锁定的“尝试”方法,或者立即失败而不会阻塞。
看
"Threading Programming Guide: Synchronization"进行概述。
请注意,
@synchronized
(与其他锁定机制相反)隐式地向该块添加了异常处理程序,以便如果抛出异常,则释放互斥锁。
@synchronized
也是一个递归锁,即同一线程可以进入 protected 代码没有阻塞。如果这与您的代码有关,则必须使用
NSRecursiveLock
或具有“递归”属性的Posix互斥锁。请注意,为此目的使用简单的实例变量
_isBeingSync
竞争条件,将无法安全工作。关于objective-c - 如何检查对象是否正在@synchronized,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17396945/