并行添加到数组 [英] Adding to array in parallel

查看:152
本文介绍了并行添加到数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Grand Central Dispatch将一个数组的元素转换为另一个数组.我在源数组上调用dispatch_apply,将其转换为零个或多个项目,然后将它们添加到目标数组.这是一个简化的示例:

I'm using Grand Central Dispatch to transforms elements of one array into another. I call dispatch_apply on the source array, transform it into zero or more items, then add them to the destination array. This is a simplified example:

let src = Array(0..<1000)
var dst = [UInt32]()

let queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT)
dispatch_apply(src.count, queue) { i in
    dst.append(arc4random_uniform(UInt32(i))) // <-- potential error here
}

print(dst)

有时append行出现错误.错误始终是以下之一:

I sometimes get an error on the append line. The error is always one of:

1. malloc: *** error for object 0x107508f00: pointer being freed was not allocated
2. fatal error: UnsafeMutablePointer.destroy with negative count
3. fatal error: Can't form Range with end < start

我猜这是由于append不是线程安全的.我做错了什么以及如何解决?

I guess this is due to append not being thread-safe. What did I do wrong and how to fix it?

推荐答案

正如您所发现的,Swift可能会重新定位数组以提高内存效率.当您运行多个append时,肯定会发生.我的猜测是,与转换相比,追加到数组的操作成本非常低.您可以创建一个串行队列,仅用于扩展dst数组:

As you have discovered, Swift may relocate the array for memory efficiency. When you run multiple append, it's bound to happen. My guess is that appending to the array is a very low cost operation compared to your transformation. You can create a serial queue just to extend the dst array:

let src = Array(0..<1000)
var dst = [UInt32]()

let queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT)
let serialQueue = dispatch_queue_create("mySerialQueue", DISPATCH_QUEUE_SERIAL)
let serialGroup = dispatch_group_create()

dispatch_apply(src.count, queue) { i in
    let result = arc4random_uniform(UInt32(i)) // Your long-running transformation here
    dispatch_group_async(serialGroup, serialQueue) {
        dst.append(result)
    }
}

// Wait until all append operations are complete
dispatch_group_wait(serialGroup, DISPATCH_TIME_FOREVER)

这篇关于并行添加到数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆