Pthread_mutex_t VS @ synchronized block?

static pthread_mutex_t gLock; //global pthread_mutex_init(&gLock,NULL); //in init pthread_mutex_lock(&gLock); for(int i=0;i<[message count];i++) CFSetAddValue(mSet, [message objectAtIndex:i]); pthread_mutex_unlock(&gLock); 

My cocoa application goes into non-responsive mode with pthread_mutex_t.

 @synchronized(mSet) { for(int i=0;i<[message count];i++) CFSetAddValue(mSet, [message objectAtIndex:i]); } 

My application works fine with a synchronized block.

Why?

+6
source share
2 answers

You are comparing a global lock (one lock for all instances) with a recursive lock at the object level (one lock per instance, which can be obtained several times from the same thread). They, as a rule, are not interchangeable - they act and are very different from each other.

The good news: you can use pthread_mutex_t as a recursive lock that is unique to each instance to achieve the same degree of protection as @synchronized . Using pthread_mutex_t also makes blocking acquisitions much, much faster.

To achieve the same effect as @synchronized using the pthread mutex, declare pthread_mutex_t gLock as an instance variable, then initialize it as a recursive mutex in -init . Finally, destroy the mutexes in -dealloc .

Of course, sub- and base classes may need access to this lock if they rely on @synchronized semantics to do the right thing through a hierarchy of objects.

@synchronized slower than veeeeeeery compared to the recursive pthread mutex (the last time I checked).

+8
source

Justin is right; however, there is another detail that is exception handling. From https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html this advice comes:

As a precaution, the @synchronized block implicitly adds an exception handler to the protected code. This handler automatically releases the mutex if an exception occurs. This means that to use the @synchronized directive, you must also enable Objective-C exception handling in your code. If you do not need additional overhead caused by an implicit exception handler, you should consider using lock classes.

If [message count] can throw exceptions that can jump over your unlock code and wedge you.

0
source

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


All Articles