簡體   English   中英

Swift 3 DispatchGroup單成功DispatchWorkItem

[英]Swift 3 DispatchGroup single success DispatchWorkItem

這是交易。 我試圖在樹上走。 但是要同時進行。 因此,每次我走到一個節點上時,我都需要同時走動它的所有節點,依此類推。 但。 我不想等待整個DispatchGroup完成以獲取結果,因為在Big O中這是最壞的情況。相反,我想取消所有其他DispatchWorkItems並在后續的工作組中保留它們。 試圖通過計算結束的任務來做到這一點。 顯然我在做錯事或誤解了如何使用它。 下面的代碼僅用於示例目的和測試想法。 考慮到現實情況,您可以在DispatchWorkItem中遞歸調用樹的當前節點的另一個handle函數。

func handle(completion: @escaping (Int) -> Void) {
    var result: Int = 0


    var count = 7
    let group = DispatchGroup()
    let queue = DispatchQueue(label: "q", attributes: .concurrent)

    var items = [DispatchWorkItem]()

    let item1 = DispatchWorkItem(flags: .inheritQoS) {
        for _ in 0...1000 { continue }
        count -= 1
        group.leave()
        print("left 1")
    }
    let item2 = DispatchWorkItem(flags: .inheritQoS) {
        for _ in 0...2000 { continue }
        count -= 1
        group.leave()
        print("left 2")
    }
    let item3 = DispatchWorkItem(flags: .inheritQoS) {
        for _ in 0...6000 { continue }
        count -= 1
        group.leave()
        print("left 3")
    }
    let item4 = DispatchWorkItem(flags: .inheritQoS) {
        for _ in 0...3000 { continue }
        result = 42

        items.forEach { $0.cancel() }

        for _ in 0..<count {
            group.leave()
        }

        print("ok; left 4")
    }
    let item5 = DispatchWorkItem(flags: .inheritQoS) {
        for _ in 0...50000 { continue }
        count -= 1

        group.leave()
        print("left 5")
    }
    let item6 = DispatchWorkItem(flags: .inheritQoS) {
        for _ in 0...6000 { continue }
        count -= 1
        group.leave()
        print("left 6")
    }
    let item7 = DispatchWorkItem(flags: .inheritQoS) {
        for _ in 0...8000 { continue }
        count -= 1
        group.leave()
        print("left 7")
    }

    items.append(item1)
    items.append(item2)
    items.append(item3)
    items.append(item4)
    items.append(item5)
    items.append(item6)
    items.append(item7)

    for item in items {
        group.enter()
        queue.async(execute: item)
    }

    group.notify(queue: queue) { 
        return
    }
}

test() {
    handle { result in
        print(result)
    }

}

您不能一次從多個線程讀取和寫入計數變量。 您需要對互斥鎖進行計數。 您遇到不穩定的情況,試圖從多個線程訪問和/或更改計數。 另外,您應該設計為根本不需要計數。

一些想法:

  1. 如果要取消耗時的任務,則需要定期檢查isCancelled 參見https://stackoverflow.com/a/38372384/1271826

  2. 如果要更新多個線程中的countitems ,則必須同步該交互(例如,使用鎖或專用串行隊列)。 IntArray不是線程安全的,因此您必須自己進行管理。

  3. 跟蹤count並使用DispatchGroup並跟蹤您自己的DispatchWorkItem引用集合將需要一些工作。 操作隊列使您擺脫了所有這些。 話雖這么說,如果需要最大的效率,那么也許您想留在調度隊列中,但這只是很多工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM