Sometimes I wrote the following code to synchronized a routine:
@synchronized(objToBeSync){ .... }
When two threads try to access the sync block at the same time, one will block the others, until the one exits the sync block.
However, sometimes I don't want one blocks the other, but the others check if the object is being synchronized, and then do some other thing so I have to do sth like this:
@synchronized(objToBeSync){
_isBeingSync = YES;
...
_isBeingSync = NO;
}
_isBeingSync
is an additional var on checking if objToBeSync is being sync. The other threads check _isBeingSync
before they continue their work. And my question is that does objc provide sth to check objToBeSync directly but not introduce an additional var to mark down its status.
The compiler translates
@synchronized(objToBeSync) { ... }
intoand from the Objective-C Runtime Source Code (objc-sync.mm, objc-os.mm, objc-lockdebug.mm, objc-os.h) one can see that these functions mainly do a
where
m->mutex
is apthread_mutex_t
with thePTHREAD_MUTEX_RECURSIVE
attribute that is associated with the objectobjToBeSync
, using a cache internal to the runtime.So the direct answer to your question is: No, there is no public API to get the "locked" status of an object, and accessing the internal mutex seems almost impossible to me.
Therefore, you should use a different locking mechanism if you have that requirement, e.g. a Posix Mutex Lock,
NSLock
orNSRecursiveLock
. All these locks have a "try" method that can be used to aquire the lock, or fail immediately without blocking.See "Threading Programming Guide: Synchronization" for an overview.
Note that
@synchronized
(in contrast to the other locking mechanisms) implicitly adds an exception handler to the block so that the mutex is released if an exception is thrown.Also
@synchronized
is a recursive lock, i.e. the same thread can enter the protected code without blocking. If that is relevant to your code, you would have to useNSRecursiveLock
or a Posix Mutex Lock with the "recursive" attribute.Note that using a simple instance variable
_isBeingSync
for this purpose is subject to race conditions and will not work safely.