Sobes.tech
Middle+

Co się dzieje z kolejką równoległą podczas uruchomienia operacji bariery?

sobes.tech AI

Odpowiedź od AI

Kolejka równoległa tymczasowo staje się kolejką sekwencyjną. Zadania wykonywane przed barierą kończą się, a następnie wykonywane jest tylko zadanie bariery. Nowe zadania nie są uruchamiane do czasu zakończenia zadania bariery. Po zakończeniu zadania bariery kolejka przywraca równoległe wykonywanie dla pozostałych zadań.

Przykład użycia async/await z barierą opartą na actor:

actor SharedDataManager {
    private var data: [String] = ["Initial"]

    func addData(_ item: String) { // Metoda mutująca - bariera
        data.append(item)
        print("Dodano \(item). Aktualne dane: \(data)")
    }

    func processData(completion: @escaping ([String]) -> Void) { // Nie mutująca
        // Nie wymaga bariery, może być wykonywana równolegle z innymi nie mutującymi
        DispatchQueue.global().async {
            // Intensywne przetwarzanie...
            let result = self.data.map { $0.uppercased() }
            completion(result)
        }
    }

    func getData() -> [String] { // Metoda nie mutująca - nie bariera
        return data
    }
}

Przykład użycia Grand Central Dispatch (GCD) z barierą:

let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)

func performTasks() {
    concurrentQueue.async {
        print("Zadanie 1 rozpoczęte")
        Thread.sleep(forTimeInterval: 1) // Symulacja pracy
        print("Zadanie 1 zakończone")
    }

    concurrentQueue.async {
        print("Zadanie 2 rozpoczęte")
        Thread.sleep(forTimeInterval: 1)
        print("Zadanie 2 zakończone")
    }

    // Zadanie bariery
    concurrentQueue.async(flags: .barrier) {
        print("Zadanie bariery rozpoczęte")
        Thread.sleep(forTimeInterval: 2) // Symulacja pracy wymagającej wyłącznego dostępu
        print("Zadanie bariery zakończone")
    }

    concurrentQueue.async {
        print("Zadanie 3 rozpoczęte")
        Thread.sleep(forTimeInterval: 1)
        print("Zadanie 3 zakończone")
    }

    concurrentQueue.async {
        print("Zadanie 4 rozpoczęte")
        Thread.sleep(forTimeInterval: 1)
        print("Zadanie 4 zakończone")
    }
}

// Wyjście będzie pokazywać, że Zadanie 3 i Zadanie 4 zaczynają się dopiero po zakończeniu Zadania bariery.