ios Swift中多线程环境下的写时拷贝

csga3l58  于 2023-01-22  发布在  iOS
关注(0)|答案(1)|浏览(119)

我读过关于Arrays中优化的写入时复制概念和Swift中的其他数据结构。
我想知道的是写入时复制在多线程环境中是如何工作的。

let arr1 = [1, 2, 3, 4]
    let arr2 = arr1
    arr1.withUnsafeBytes { print("arr1:", $0.baseAddress) } //0x000060000007ee60
    arr2.withUnsafeBytes { print("arr2:", $0.baseAddress) } //0x000060000007ee60
    
    DispatchQueue.global(qos: .default).async {
        let arr3 = arr1
        arr3.withUnsafeBytes { print("arr3:", $0.baseAddress) } //0x000060000007ee60
    }

在上面的代码中,arr1arr2最初与copy-on-write中的预期地址相同。但是,arr3也与arr1arr2共享相同的内存,尽管它在不同的线程上执行。
据我所知,每个线程都有不同的堆栈分配。那么为什么arr3仍然共享相同的位置?

h43kikqp

h43kikqp1#

你不是在看数组的地址,你是在看数组的内部后备存储的地址,它是共享的,堆分配的。
如果您想查看堆栈分配的数组容器的地址(指向后备存储器的部分),那么您的意思是:

var arr1 = [1, 2, 3, 4]
var arr2 = arr1
withUnsafePointer(to: &arr1) { print("arr1:", $0) }
withUnsafePointer(to: &arr2) { print("arr2:", $0) }

DispatchQueue.global(qos: .default).async {
    let arr3 = arr1
    withUnsafePointer(to: arr3) { print("arr3:", $0) }
}

// =>
arr1: 0x0000000122d671e0   // local stack
arr2: 0x0000000122d671e8   // local stack (next address)
arr3: 0x0000700000e48d10   // heap

我相信这是你所期待的结果。

相关问题