在Swift中的多线程环境中进行Copy-on-Write

时间:2018-06-19 06:18:52

标签: ios arrays swift copy-on-write ios-multithreading

我已经在using System.Threading.Tasks; namespace AproReports.DAL.Services.RequestProvider { public interface IRequestProvider { Task<TResult> GetAsync<TResult>(string uri, string token = ""); Task<TResult> PostAsync<TResult>(string uri, TResult data, string token = "", string header = ""); Task<TResult> PutAsync<TResult>(string uri, TResult data, string token = "", string header = ""); Task DeleteAsync(string uri, string token = ""); } } 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 } arr1最初的地址与arr2中的预期相同。但是,copy-on-write也与arr3arr1共享相同的内存,尽管它在不同的线程上执行。

据我所知,每个线程都有不同的堆栈分配。那么为什么arr2仍在共享同一位置?

有人可以解释一下它是如何运作的。

1 个答案:

答案 0 :(得分:5)

您没有查看阵列的地址。您正在查看阵列的内部后备存储的地址,这些地址是共享和堆分配的。

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

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

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