[swift-users] Swift and Threads

Gerriet M. Denkmann gerriet at mdenkmann.de
Tue Sep 13 03:01:58 CDT 2016


> On 13 Sep 2016, at 14:49, Quinn The Eskimo! via swift-users <swift-users at swift.org> wrote:
> 
> 
> On 13 Sep 2016, at 05:03, Gerriet M. Denkmann via swift-users <swift-users at swift.org> wrote:
> 
>> Or is the code fundamentally wrong …?
> 
> This one.
> 
> You’re accessing a mutable value (`bitfield`) from multiple threads.  Swift does not support that, even in situations like this where you’re sure that the items are preallocated and that the threads are accessing non-overlapping values.
> 
> As to how you fix this, it kinda depends on your final use for the array.  If you’re OK with the results being split into per-thread chunks, you can have each thread work on its own chunk and then pass the results back to the ‘main’ thread when it’s done.  OTOH, if you need your results in one big array, things get tricky.

Stephen J. Butler just suggested a solution (on CocoaDev) which works and is fast and uses no additional memory.

Here it is:

let nbrOfThreads = 8
let step = 2
let itemsPerThread = number * step
let bitLimit = nbrOfThreads * itemsPerThread
var bitfield = [Bool](count: bitLimit, repeatedValue: false)

let queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 );

bitfield.withUnsafeMutableBufferPointer { (inout bitfieldBuffer : UnsafeMutableBufferPointer<Bool>) -> () in
    dispatch_apply( Int(nbrOfThreads), queue ) { ( idx: size_t) -> Void in
        let startIndex = itemsPerThread * Int(idx)
        let endIndex = min( startIndex + itemsPerThread, bitLimit )
        if talk { print("Thread[\(idx)] does \(startIndex) ..< \(endIndex)") }

        var currIndex = startIndex
        while( currIndex < endIndex )
        {
            bitfieldBuffer[currIndex] = true
            currIndex += step
        }
    }
}

I hope that this is really thread-safe (testing it, I have no problems so far).

Kind regards,

Gerriet.



More information about the swift-users mailing list