How to check if an @ object is synchronized

Sometimes I wrote the following code to synchronize the procedure:

@synchronized(objToBeSync){ .... } 

When two threads try to simultaneously access the synchronization block, one will block the others until it exits the synchronization block.

However, sometimes I don’t want one block to block another, and others check if the object is synchronized, and then do something else, so I need to do the following:

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

_isBeingSync is an additional var variable when checking objToBeSync synchronization. Other threads check _isBeingSync before they continue. And my question is that objc provides sth for checking objToBeSync directly, but doesn't introduce an extra var to mark its status.

+4
source share
1 answer

The compiler translates @synchronized(objToBeSync) { ... } to

 callq _objc_sync_enter ... callq _objc_sync_exit 

and from Objective-C the runtime source code (objc-sync.mm, objc-os.mm, objc-lockdebug.mm, objc-os.h) you can see that these functions basically perform

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

where m->mutex is pthread_mutex_t with the PTHREAD_MUTEX_RECURSIVE attribute that is associated with the objToBeSync object using a cache internal to the runtime.

Thus, a direct answer to your question: No, there is no public API to get the "blocked" status of an object, and access to the internal mutex seems almost impossible for me.

Therefore, you should use a different locking mechanism if you have this requirement, for example Mutex Posix Lock, NSLock or NSRecursiveLock . All these locks have a “try” method, which can be used to access the lock or immediately crash without locking.

See “Thread Programming Guide: Synchronization” for an overview.

Note that @synchronized (unlike other locking mechanisms) implicitly adds an exception handler to the block, so the mutex is freed if an exception is thrown.

Also @synchronized is a recursive lock, i.e. the same thread can enter the protected code without blocking. If this is relevant to your code, you will have to use NSRecursiveLock or Lock Mutex Posix with the "recursive" attribute.

Please note that using a simple _isBeingSync instance _isBeingSync for this purpose is race-specific and will not work safely.

+4
source

Source: https://habr.com/ru/post/1489022/


All Articles