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

@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互斥锁,NSLockNSRecursiveLock。所有这些锁都有一个
可用于获取锁定的“尝试”方法,或者立即失败而不会阻塞。


"Threading Programming Guide: Synchronization"进行概述。

请注意,@synchronized(与其他锁定机制相反)隐式地向该块添加了异常处理程序,以便
如果抛出异常,则释放互斥锁。
@synchronized也是一个递归锁,即同一线程可以进入 protected
代码没有阻塞。如果这与您的代码有关,则必须使用NSRecursiveLock或具有“递归”属性的Posix互斥锁。

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

关于objective-c - 如何检查对象是否正在@synchronized,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17396945/

10-12 03:41