How do I check if an object is being @synchronized

不问归期 提交于 2019-12-06 03:07:08

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/17396945/how-do-i-check-if-an-object-is-being-synchronized

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!