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) { ... }
into
callq _objc_sync_enter
...
callq _objc_sync_exit
and 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
pthread_mutex_lock(m->mutex);
...
pthread_mutex_unlock(m->mutex);
where m->mutex
is a pthread_mutex_t
with the PTHREAD_MUTEX_RECURSIVE
attribute
that is associated with the object objToBeSync
, 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
or NSRecursiveLock
. 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 use
NSRecursiveLock
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With