MST

星途 面试题库

面试题:Objective-C中死锁通常在什么场景下发生,请举例说明

请阐述在Objective-C编程中,哪些常见的代码逻辑或者资源竞争场景容易导致死锁现象,并给出一个简单的Objective-C代码示例来体现这种死锁场景。
26.0万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

常见导致死锁的场景

  1. 递归锁与互斥锁混用:在递归锁的临界区内尝试获取互斥锁,而在互斥锁的临界区内又尝试获取递归锁,形成循环依赖。
  2. 多线程资源竞争:多个线程按照不同顺序获取多个锁。例如线程A先获取锁1,再尝试获取锁2;线程B先获取锁2,再尝试获取锁3;线程C先获取锁3,再尝试获取锁1,此时就会形成死锁。
  3. 锁的嵌套使用不当:在已经持有一个锁的情况下,在不同层次的代码中再次获取同一个锁,而没有适当的处理,也可能导致死锁。

代码示例

#import <Foundation/Foundation.h>

@interface DeadlockExample : NSObject

@property (nonatomic, strong) NSLock *lock1;
@property (nonatomic, strong) NSLock *lock2;

@end

@implementation DeadlockExample

- (instancetype)init {
    self = [super init];
    if (self) {
        _lock1 = [[NSLock alloc] init];
        _lock2 = [[NSLock alloc] init];
    }
    return self;
}

- (void)thread1Function {
    [self.lock1 lock];
    NSLog(@"Thread 1 acquired lock1");
    sleep(1);
    [self.lock2 lock];
    NSLog(@"Thread 1 acquired lock2");
    [self.lock2 unlock];
    [self.lock1 unlock];
}

- (void)thread2Function {
    [self.lock2 lock];
    NSLog(@"Thread 2 acquired lock2");
    sleep(1);
    [self.lock1 lock];
    NSLog(@"Thread 2 acquired lock1");
    [self.lock1 unlock];
    [self.lock2 unlock];
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        DeadlockExample *example = [[DeadlockExample alloc] init];
        dispatch_queue_t queue1 = dispatch_queue_create("com.example.queue1", DISPATCH_QUEUE_CONCURRENT);
        dispatch_queue_t queue2 = dispatch_queue_create("com.example.queue2", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue1, ^{
            [example thread1Function];
        });
        
        dispatch_async(queue2, ^{
            [example thread2Function];
        });
        
        dispatch_main();
    }
    return 0;
}

在上述代码中,thread1Functionthread2Function分别在不同线程中执行,thread1Function先获取lock1再获取lock2thread2Function先获取lock2再获取lock1,如果两个线程同时执行,就会发生死锁。