简体   繁体   English

pthread_mutex_t VS @synchronized块?

[英]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 is going in not responding mode with pthread_mutex_t. 我的cocoa应用程序使用pthread_mutex_t进入无响应模式。

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

My application is working fine with synchronized block. 我的应用程序与synchronized块一起工作正常。

Why? 为什么?

You're comparing a global lock (one lock for all instances) to an object level recursive lock (one lock per instance, which may be acquired multiple times from the same thread). 您将全局锁(所有实例的一个锁)与对象级递归锁(每个实例一个锁,可以从同一个线程多次获取)进行比较。 These are not generally interchangeable -- they operate and protect very different from each other. 这些通常不可互换 - 它们的操作和保护彼此非常不同。

The good news is, you can use pthread_mutex_t as a recursive lock which is unique to each instance in order to achieve the same degree of protection as @synchronized . 好消息是,您可以使用pthread_mutex_t作为递归锁,这对每个实例都是唯一的,以实现与@synchronized相同的保护程度。 Using pthread_mutex_t also makes lock acquisitions much, much faster. 使用pthread_mutex_t也可以更快,更快地进行锁定采集。

To achieve the same effect as @synchronized using a pthread mutex, declare pthread_mutex_t gLock as an instance variable, then initialize it as a recursive mutex in -init . 为了达到相同的效果@synchronized使用Pthread互斥,声明pthread_mutex_t gLock作为一个实例变量,然后初始化它作为一个递归互斥-init Finally, destroy the mutex in -dealloc . 最后,在-dealloc销毁互斥锁​​。

Of course, sub- and base- classes may need access to this lock if they relied on the semantics of @synchronized to do the right thing through the object hierarchy. 当然,如果子类和基类依赖于@synchronized的语义来通过对象层次结构做正确的事情,则可能需要访问此锁。

@synchronized is veeeeeeery slow in comparison to a recursive pthread mutex (last I checked). 与递归的pthread互斥锁(我最后检查过)相比, @synchronized的速度很慢。

Justin is right; 贾斯汀是对的; there is also another detail, however, which is exception handling. 然而,还有另一个细节,即异常处理。 From https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html comes this tip: 来自https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html的提示:

As a precautionary measure, the @synchronized block implicitly adds an exception handler to the protected code. 作为预防措施,@ synchronized块隐式地向受保护代码添加异常处理程序。 This handler automatically releases the mutex in the event that an exception is thrown. 如果抛出异常,此处理程序会自动释放互斥锁。 This means that in order to use the @synchronized directive, you must also enable Objective-C exception handling in your code. 这意味着,为了使用@synchronized指令,还必须在代码中启用Objective-C异常处理。 If you do not want the additional overhead caused by the implicit exception handler, you should consider using the lock classes. 如果您不希望由隐式异常处理程序引起额外开销,则应考虑使用锁类。

If [message count] can raise exceptions that could jump over your unlock code and wedge you up. 如果[message count]可以引发可能跳过解锁代码并将您楔入的异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM