MST

星途 面试题库

面试题:Objective-C线程管理中如何处理线程间通信及数据共享问题?

在Objective-C的多线程编程场景下,经常会遇到线程间需要通信和共享数据的情况。请详细阐述处理这些问题的常见方法,并举例说明如何使用NSThread类配合其他机制来确保数据的一致性和线程安全。
43.5万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

处理线程间通信和共享数据的常见方法

  1. 锁机制
    • 互斥锁(Mutex):通过互斥访问共享资源,同一时间只有一个线程能访问。例如pthread_mutex_t,初始化后在访问共享数据前加锁,访问后解锁。
    • 自旋锁(Spin Lock):线程尝试获取锁时,如果锁不可用,它不会进入睡眠状态,而是在原地循环等待锁可用。适用于锁被持有时间较短的场景。
    • 读写锁(Read - Write Lock):允许多个线程同时读共享资源,但只允许一个线程写。读操作时使用读锁,写操作时使用写锁。
  2. 信号量(Semaphore):用于控制同时访问共享资源的线程数量。可以设置信号量的初始值,线程获取信号量时,信号量值减1,释放信号量时,信号量值加1。当信号量值为0时,其他线程获取信号量会被阻塞。
  3. 条件变量(Condition Variable):常与互斥锁一起使用,线程在满足特定条件时才继续执行。例如,一个线程等待某个条件满足,另一个线程改变条件后通知等待的线程。
  4. 队列(Queue):使用队列来管理任务,如Grand Central Dispatch(GCD)的队列或NSOperationQueue。可以将任务添加到队列中,队列按照一定规则顺序执行任务,避免了多线程同时访问共享资源的冲突。
  5. 原子属性(Atomic Property):在属性声明时使用atomic关键字,编译器会生成线程安全的访问器方法。但注意,这只能保证属性的getter和setter方法是线程安全的,对于复杂的操作仍可能需要额外的同步机制。

使用NSThread类配合其他机制确保数据一致性和线程安全示例

#import <Foundation/Foundation.h>

// 定义共享数据
@interface SharedData : NSObject
@property (nonatomic, assign) int value;
@end

@implementation SharedData
@end

// 定义一个锁
static pthread_mutex_t mutex;

// 线程执行的函数
void *threadFunction(void *data) {
    SharedData *shared = (__bridge SharedData *)data;
    // 加锁
    pthread_mutex_lock(&mutex);
    for (int i = 0; i < 5; i++) {
        shared.value++;
        NSLog(@"Thread %@ incremented value to %d", [NSThread currentThread], shared.value);
    }
    // 解锁
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 初始化锁
        pthread_mutex_init(&mutex, NULL);
        
        SharedData *sharedData = [[SharedData alloc] init];
        sharedData.value = 0;
        
        // 创建两个线程
        NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(threadFunction:) object:(__bridge id)(sharedData)];
        NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(threadFunction:) object:(__bridge id)(sharedData)];
        
        // 启动线程
        [thread1 start];
        [thread2 start];
        
        // 等待线程执行完毕
        [thread1 join];
        [thread2 join];
        
        // 销毁锁
        pthread_mutex_destroy(&mutex);
        
        NSLog(@"Final value: %d", sharedData.value);
    }
    return 0;
}

在上述示例中,我们定义了一个SharedData类来表示共享数据,使用pthread_mutex_t类型的互斥锁来确保多个线程对sharedData.value的访问是线程安全的。每个线程在访问共享数据前加锁,访问完毕后解锁。这样就保证了数据的一致性和线程安全。