需求
有A、B、C、D、E、F 六個(gè)任務(wù),D依賴A、B的結(jié)果,E依賴B、C的結(jié)果,F(xiàn)依賴D、E的結(jié)果,A、B、C互不依賴,D、F之間不依賴,可以并發(fā),整體要盡快執(zhí)行完成。
參考實(shí)現(xiàn)
一、通過 OperationQueue 添加依賴關(guān)系實(shí)現(xiàn)
/// 通過 OperationQueue 控制異步任務(wù)調(diào)度
func testOperation() {
// 創(chuàng)建異步任務(wù)
let operaA = BlockOperation {
self.execTask("A")
}
let operaB = BlockOperation {
self.execTask("B")
}
let operaC = BlockOperation {
self.execTask("C")
}
let operaD = BlockOperation {
self.execTask("D")
}
let operaE = BlockOperation {
self.execTask("E")
}
let operaF = BlockOperation {
self.execTask("F")
}
let operaG = BlockOperation {
self.printf("\nFinished\n")
}
// 添加依賴關(guān)系
operaD.addDependency(operaA)
operaD.addDependency(operaB)
operaE.addDependency(operaB)
operaE.addDependency(operaC)
operaF.addDependency(operaD)
operaF.addDependency(operaE)
operaG.addDependency(operaF)
let queue = OperationQueue()
// Adds the specified operation to the receiver.
queue.addOperation(operaA)
queue.addOperation(operaB)
queue.addOperation(operaC)
queue.addOperation(operaD)
queue.addOperation(operaE)
queue.addOperation(operaF)
queue.addOperation(operaG)
// 設(shè)置最大并發(fā)數(shù)
queue.maxConcurrentOperationCount = queue.operations.count
}
二、通過 DispatchGroup 控制異步任務(wù)調(diào)度
/// 通過 DispatchGroup 控制異步任務(wù)調(diào)度
func testDispatchGroup() {
// 創(chuàng)建DispatchGroup
let groupD = DispatchGroup() // A、B -> D
let groupE = DispatchGroup() // B、C -> E
let groupF = DispatchGroup() // D、E -> F
let groupFinish = DispatchGroup() // 完成
// 創(chuàng)建異步任務(wù)
let queueA = DispatchQueue(label: "A")
let queueB = DispatchQueue(label: "B")
let queueC = DispatchQueue(label: "C")
let queueD = DispatchQueue(label: "D")
let queueE = DispatchQueue(label: "E")
let queueF = DispatchQueue(label: "F")
groupD.enter()
queueA.async {
self.execTask("A")
groupD.leave()
}
groupD.enter()
groupE.enter()
queueB.async {
self.execTask("B")
groupD.leave()
groupE.leave()
}
groupE.enter()
queueC.async {
self.execTask("C")
groupE.leave()
}
groupF.enter()
groupD.notify(queue: DispatchQueue.global()) {
// A、B任務(wù)已完成,開始D任務(wù)
queueD.async {
self.execTask("D")
groupF.leave()
}
}
groupF.enter()
groupE.notify(queue: DispatchQueue.global()) {
// B、C任務(wù)已完成,開始E任務(wù)
queueE.async {
self.execTask("E")
groupF.leave()
}
}
groupFinish.enter()
groupF.notify(queue: DispatchQueue.global()) {
// D、E任務(wù)已完成,開始F任務(wù)
queueF.async {
self.execTask("F")
groupFinish.leave()
}
}
groupFinish.notify(queue: DispatchQueue.global()) {
self.printf("\nFinished\n")
}
}
三、通過信號量控制異步任務(wù)調(diào)度
/// 通過信號量控制異步任務(wù)調(diào)度
func testDispatchSemaphore() {
let value = 0
let semaphoreD = DispatchSemaphore(value: value) // A、B -> D
let semaphoreE = DispatchSemaphore(value: value) // B、C -> E
let semaphoreF = DispatchSemaphore(value: value) // E、D -> F
let semaphoreG = DispatchSemaphore(value: value) // 完成
// 創(chuàng)建異步任務(wù)
let queueA = DispatchQueue(label: "A")
let queueB = DispatchQueue(label: "B")
let queueC = DispatchQueue(label: "C")
let queueD = DispatchQueue(label: "D")
let queueE = DispatchQueue(label: "E")
let queueF = DispatchQueue(label: "F")
queueA.async {
self.execTask("A")
}
queueB.async {
self.execTask("B")
semaphoreD.signal()
}
queueC.async {
self.execTask("C")
semaphoreE.signal()
}
semaphoreD.wait()
queueD.async {
Thread.sleep(forTimeInterval: 2)
self.execTask("D")
}
semaphoreE.wait()
queueE.async {
Thread.sleep(forTimeInterval: 2)
self.execTask("E")
semaphoreF.signal()
}
semaphoreF.wait()
queueF.async {
self.execTask("F")
semaphoreG.signal()
}
semaphoreG.wait()
printf("\nFinished\n")
}
四、ReactiveSwift信號流
typealias SignalProducerHandler = SignalProducer<String, Error>
/// 通過ReactiveSwift信號流控制異步任務(wù)調(diào)度
private func testSignalProducer() {
/// 創(chuàng)建異步任務(wù)
let signalA = setupSignal("A")
let signalB = setupSignal("B")
let signalC = setupSignal("C")
let signalD = setupSignal("D")
let signalE = setupSignal("E")
let signalF = setupSignal("F")
/// A、B、C并發(fā)請求
SignalProducer.merge(signalA, signalB, signalC).collect().on(
failed: { error in
self.printf("\(error)")
}
).flatMap(.concat, { (_) -> SignalProducer<[String], Error> in
// D、E并發(fā)請求
return SignalProducer.merge(signalD, signalE).collect().on(
failed: { error in
self.printf("\(error)")
}
)
}).flatMap(.concat) { (data) -> SignalProducerHandler in
// 請求F
return signalF
}.on(
failed: { error in
self.printf("\(error)")
},
completed: {
self.printf("\nFinished\n")
},
value: { data in
self.printf("\ndata: \(data)\n")
}
).start()
}
問題:
這里實(shí)現(xiàn)的是【A、B、C并發(fā)請求】,成功后再串聯(lián)【D、E并發(fā)請求】的結(jié)果,最后再請求F,與題目中的“
整體要盡快執(zhí)行完成”描述不太相符,目前沒有想到怎么控制請求B重復(fù)請求的辦法,做標(biāo)記還是用其他方法,待求解。。。
私有成員
private let _time = 3
// mock異步任務(wù)
private func execTask(_ taskName: String) {
for _ in 0..<_time { printf(taskName) }
}
/// 打印log
private func printf(_ items: String) {
print(items, terminator: "\t")
}
// 創(chuàng)建異步請求信號
private func setupSignal(_ taskName: String) -> SignalProducerHandler {
return SignalProducerHandler() {[weak self] sink, _ in
DispatchQueue(label: taskName).async {
self?.execTask(taskName)
}
sink.send(value: taskName)
sink.sendCompleted()
}
}
參考log輸出
A A A C C C B B B E D D D E E F F F
Finished
A A A B B B C C C D D D E E E F F F
Finished
B C A A A C C B B D E D E E D F F F
Finished