Hello. I have a piece of program where I need to pass an array to two async queues and at the end of execution of that queues I need to synchronize that array with the main queue. But I get the error Data race in Runner.Forum.run() -> () at 0x7b0800029860 and I absolutely don't know how to do it with out the error. I attached the code

struct Forum {
    let queue1 = DispatchQueue(label: "Pollination")
    let queue2 = DispatchQueue(label: "Return to the hive")
    struct Bee { let name: String }
    struct Swarm { var bees = [Bee]() }
    func run() {
    
    let bee1 = Bee(name: "1")
    let bee2 = Bee(name: "2")
    let bee3 = Bee(name: "3")
    let bee4 = Bee(name: "4")
    
    var swarm = Swarm()
    var copy2 = swarm
    var copy1 = swarm
    
    queue1.async {
        copy1.bees.append(bee1)
        copy1.bees.append(bee2)
        print("queue1: \(copy1)")
        swarm = copy1 // need synchronies the result of that queue
    }
    
    queue2.async {
        copy2.bees.append(bee3)
        copy2.bees.append(bee4)
        print("queue2: \(copy2)")
    }
    
    let _ = readLine() // need press button and Enter here
    print("after swarm: \(swarm)") // Data race in Runner.Forum.run() -> () at 0x7b0800029860
    print("after copy1: \(copy1)")
    print("after copy2: \(copy2)")
}

Arrays are copy on write, so they will use the same internal buffer until one of the "copies" are modified, then it will copy the whole internal buffer to a new place. So in order to avoid accessing the same internal buffer from multiple queues, you have to force a copy.

The easiest is to just append then remove an element from one of them.

But if you want a generic makeUnique function for Array, you can use this initializer to avoid double initialization or multiple resizes: init(unsafeUninitializedCapacity:initializingWith:) | Apple Developer Documentation

1 Like

ha ha. Does it really work?

Сopying the code to the main.swift and removing run() function gets the same Data Race warning. But it is indeed read access. So maybe the warning is not critical here. But there is, and question is what does it mean. And another question is how to correct sync the result to the main queue. Because simple sync makes nonsense the background execution of the next tasks.

But it will cause Access Race and crash