在一个队列解锁 NSRecursiveLock 后,其他队列仍在等待
我有一些代码不是线程安全的,所以我尝试使用 NSRecursiveLock 来防止我的工作队列和主线程同时访问某些属性。我创建了两个工作队列(工作队列和等待队列),工作队列来做一些繁重的工作。为了防止阻塞主线程,我创建了另一个等待队列来等待锁,这样我就可以在获得锁后异步到主线程。
我面临两个问题:
- 工作队列解锁后,等待队列仍在等待。
- 代码将得到两种输出
我认为输出应该是
1. work queue get lock
2. wait queue wait lock
3. post notification from work queue
noti called
unlock
get lock
4. main thread do work
但我得到输出:
[Output 1]
1. work queue get lock
2. wait queue wait lock
3. post notification from work queue
noti called
unlock
[Output 2]
1. work queue get lock
2. wait queue wait lock
get lock
4. main thread do work
3. post notification from work queue
noti called
unlock
@interface ViewController ()
@property (nonatomic) NSLock *lock;
@property (nonatomic) NSRecursiveLock *recursiveLock;
@property (nonatomic) dispatch_queue_t queue;
@property (nonatomic) dispatch_queue_t lockWaitQueue;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_queue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
_lockWaitQueue = dispatch_queue_create("wait_queue", DISPATCH_QUEUE_SERIAL);
[[NSNotificationCenter defaultCenter] addObserverForName:@"noti" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
NSLog(@"noti called");
}];
_lock = [NSLock new];
_recursiveLock = [NSRecursiveLock new];
[self tryFixDeadLockCace];
}
- (void)tryFixDeadLockCace {
NSRecursiveLock *lock = _recursiveLock;
dispatch_queue_t queue = _queue;
dispatch_queue_t lockWaitQueue = _lockWaitQueue;
NSLog(@"1. work queue get lock");
dispatch_async(queue, ^{
[lock lock];
dispatch_async(dispatch_get_main_queue(), ^{
dispatch_async(lockWaitQueue, ^{
NSLog(@"2. wait queue wait lock");
[lock lock];
NSLog(@"get lock");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"4. main thread do work");
[lock unlock];
});
});
});
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), queue, ^{
NSLog(@"3. post notification from work queue");
[[NSNotificationCenter defaultCenter] postNotificationName:@"noti" object:nil];
NSLog(@"unlock");
[lock unlock];
});
}
- (void)noti {
}
@end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果用户使用NSRecursiveLock,不应该使用GCD,因为锁定和解锁可能不在同一个线程上

if user NSRecursiveLock, should not use GCD, because lock an unlock may not on the same thread
