@synchronized 如何在 Objective-C 中加锁/解锁?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1215330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does @synchronized lock/unlock in Objective-C?
提问by David Lin
Does @synchronized not use "lock" and "unlock" to achieve mutual exclusion? How does it do lock/unlock then?
@synchronized 不使用“锁定”和“解锁”来实现互斥吗?那么它如何锁定/解锁呢?
The output of the following program is only "Hello World".
以下程序的输出仅为“Hello World”。
@interface MyLock: NSLock<NSLocking>
@end
@implementation MyLock
- (id)init {
return [super init];
}
- (void)lock {
NSLog(@"before lock");
[super lock];
NSLog(@"after lock");
}
- (void)unlock {
NSLog(@"before unlock");
[super unlock];
NSLog(@"after unlock");
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
MyLock *lock = [[MyLock new] autorelease];
@synchronized(lock) {
NSLog(@"Hello World");
}
[pool drain];
}
回答by Louis Gerbarg
The Objective-C language level synchronization uses the mutex, just like NSLockdoes. Semantically there are some small technical differences, but it is basically correct to think of them as two separate interfaces implemented on top of a common (more primitive) entity.
Objective-C 语言级别的同步使用互斥锁,就像使用互斥锁一样NSLock。在语义上存在一些小的技术差异,但将它们视为在公共(更原始)实体之上实现的两个独立接口基本上是正确的。
In particular with a NSLockyou have an explicit lock whereas with @synchronizedyou have an implicit lock associated with the object you are using to synchronize. The benefit of the language level locking is the compiler understands it so it can deal with scoping issues, but mechanically they behave basically the same.
特别是对于 a ,NSLock您有一个显式锁,而@synchronized您有一个与用于同步的对象关联的隐式锁。语言级锁定的好处是编译器可以理解它,因此它可以处理作用域问题,但在机制上它们的行为基本相同。
You can think of @synchronizedas a compiler rewrite:
您可以将其@synchronized视为编译器重写:
- (NSString *)myString {
@synchronized(self) {
return [[myString retain] autorelease];
}
}
is transformed into:
转化为:
- (NSString *)myString {
NSString *retval = nil;
pthread_mutex_t *self_mutex = LOOK_UP_MUTEX(self);
pthread_mutex_lock(self_mutex);
retval = [[myString retain] autorelease];
pthread_mutex_unlock(self_mutex);
return retval;
}
That is not exactly correct because the actual transform is more complex and uses recursive locks, but it should get the point across.
这并不完全正确,因为实际的转换更复杂并且使用递归锁,但它应该能说明问题。
回答by Quinn Taylor
In Objective-C, a @synchronizedblock handles locking and unlocking (as well as possible exceptions) automatically for you. The runtime dynamically essentially generates an NSRecursiveLock that is associated with the object you're synchronizing on. This Apple documentationexplains it in more detail. This is why you're not seeing the log messages from your NSLock subclass — the object you synchronize on can be anything, not just an NSLock.
在 Objective-C 中,@synchronized块会自动为您处理锁定和解锁(以及可能的异常)。运行时动态地生成一个 NSRecursiveLock,它与您正在同步的对象相关联。这个 Apple 文档更详细地解释了它。这就是为什么您没有看到来自 NSLock 子类的日志消息的原因——您同步的对象可以是任何东西,而不仅仅是 NSLock。
Basically, @synchronized (...)is a convenience construct that streamlines your code. Like most simplifying abstractions, it has associated overhead (think of it as a hidden cost), and it's good to be aware of that, but raw performance is probably not the supreme goal when using such constructs anyway.
基本上,@synchronized (...)是一种简化代码的便利构造。像大多数简化的抽象一样,它有相关的开销(将其视为隐藏的成本),意识到这一点很好,但无论如何,原始性能可能不是使用此类构造时的最高目标。
回答by Dirk Theisen
Actually
实际上
{
@synchronized(self) {
return [[myString retain] autorelease];
}
}
transforms directly into:
直接转化为:
// needs #import <objc/objc-sync.h>
{
objc_sync_enter(self)
id retVal = [[myString retain] autorelease];
objc_sync_exit(self);
return retVal;
}
This API available since iOS 2.0 and imported using...
此 API 自 iOS 2.0 起可用,并使用...
#import <objc/objc-sync.h>
回答by JP Illanes
Apple's implementation of @synchronized is open source and it can be found here. Mike ash wrote two really interesting post about this subject:
Apple 的 @synchronized 实现是开源的,可以在这里找到。Mike ash 写了两篇关于这个主题的非常有趣的帖子:
In a nutshell it has a table that maps object pointers (using their memory addresses as keys) to pthread_mutex_tlocks, which are locked and unlocked as needed.
简而言之,它有一个表,将对象指针(使用它们的内存地址作为键)映射到pthread_mutex_t锁,根据需要锁定和解锁。
回答by Pavel Minaev
It just associates a semaphore with every object, and uses that.
它只是将一个信号量与每个对象相关联,并使用它。

