MST

星途 面试题库

面试题:Swift并发编程中的并发控制与资源共享

在一个Swift应用程序中,有多个异步任务需要访问和修改共享资源(例如一个全局的用户数据结构体)。请设计一个方案,使用Swift并发的相关机制(如`actor`、`TaskGroup`等)来确保数据的一致性和线程安全,同时保证高并发情况下的性能优化,详细说明设计思路与代码实现。
35.5万 热度难度
编程语言Swift

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 使用actor来封装共享资源actor是Swift中用于隔离并发访问的结构体或类。将全局用户数据结构体封装在actor内部,这样所有对该数据的访问和修改都必须通过actor的方法,从而保证线程安全。
  2. 利用TaskGroup来管理多个异步任务TaskGroup可以方便地创建和管理多个并发任务,并且可以等待所有任务完成后再继续执行后续代码。

代码实现

// 定义全局用户数据结构体
struct UserData {
    var name: String
    var age: Int
}

// 使用actor封装用户数据
actor UserDataManager {
    private var userData: UserData

    init() {
        userData = UserData(name: "default", age: 0)
    }

    // 获取用户数据的方法
    func getUserData() -> UserData {
        userData
    }

    // 修改用户数据的方法
    func updateUserData(name: String, age: Int) {
        userData.name = name
        userData.age = age
    }
}

// 示例函数,展示如何在多个异步任务中使用UserDataManager
func performConcurrentTasks() async {
    let manager = UserDataManager()

    // 创建TaskGroup
    await withTaskGroup(of: Void.self) { group in
        // 添加任务1
        group.addTask {
            await manager.updateUserData(name: "Alice", age: 25)
        }
        // 添加任务2
        group.addTask {
            await manager.updateUserData(name: "Bob", age: 30)
        }

        // 等待所有任务完成
        for await _ in group { }
    }

    // 获取更新后的用户数据
    let finalData = await manager.getUserData()
    print("Final User Data: \(finalData.name), \(finalData.age)")
}

在上述代码中:

  1. 定义了UserData结构体来表示用户数据。
  2. UserDataManager是一个actor,它封装了UserData并提供了获取和修改数据的方法。
  3. performConcurrentTasks函数展示了如何使用TaskGroup来并发执行多个更新用户数据的任务,最后获取更新后的用户数据。由于UserDataManageractor,所以对其方法的调用会自动处理并发访问的线程安全问题。