Swift 5.1 ile Grand Central Dispatch , sorununuzu çözmek için birçok yol sunar. İhtiyaçlarınıza göre , aşağıdaki Oyun Alanı snippet'lerinde gösterilen yedi modelden birini seçebilirsiniz .
Apple Developer Eşzamanlılık Programlama Kılavuzu aşağıdakileri belirtirDispatchGroup
:
Dağıtım grupları, bir veya daha fazla görev yürütmeyi bitirinceye kadar bir iş parçacığını engellemenin bir yoludur. Bu davranışı, belirtilen tüm görevler tamamlanana kadar ilerleme kaydedemeyeceğiniz yerlerde kullanabilirsiniz. Örneğin, bazı verileri hesaplamak için birkaç görev gönderdikten sonra, bu görevleri beklemek ve ardından tamamlandığında sonuçları işlemek için bir grup kullanabilirsiniz.
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let queue = DispatchQueue(label: "com.company.app.queue", attributes: .concurrent)
let group = DispatchGroup()
queue.async(group: group) {
print("#1 started")
Thread.sleep(forTimeInterval: 5)
print("#1 finished")
}
queue.async(group: group) {
print("#2 started")
Thread.sleep(forTimeInterval: 2)
print("#2 finished")
}
group.notify(queue: queue) {
print("#3 finished")
}
/*
prints:
#1 started
#2 started
#2 finished
#1 finished
#3 finished
*/
# 2. Kullanılması DispatchGroup
, DispatchGroup
's wait()
, DispatchGroup
' nin enter()
ve DispatchGroup
'lerleave()
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let queue = DispatchQueue(label: "com.company.app.queue", attributes: .concurrent)
let group = DispatchGroup()
group.enter()
queue.async {
print("#1 started")
Thread.sleep(forTimeInterval: 5)
print("#1 finished")
group.leave()
}
group.enter()
queue.async {
print("#2 started")
Thread.sleep(forTimeInterval: 2)
print("#2 finished")
group.leave()
}
queue.async {
group.wait()
print("#3 finished")
}
/*
prints:
#1 started
#2 started
#2 finished
#1 finished
#3 finished
*/
Ayrıca karışabileceğiyle Not DispatchGroup
wait()
ile DispatchQueue
async(group:qos:flags:execute:)
veya karıştırın DispatchGroup
enter()
ve DispatchGroup
leave()
birlikte DispatchGroup
notify(qos:flags:queue:execute:)
.
Swift 4 için Grand Central Dispatch Tutorial: Raywenderlich.com'dan Bölüm 1/2 makalesi engelleri tanımlamaktadır :
Dağıtım engelleri, eşzamanlı kuyruklarla çalışırken seri tarzda bir darboğaz görevi gören bir grup işlevdir. Bir DispatchWorkItem
gönderme kuyruğuna bir gönderirken, belirli bir süre için belirtilen kuyrukta yürütülen tek öğe olması gerektiğini belirtmek için bayraklar ayarlayabilirsiniz. Bu, gönderme engelinden önce kuyruğa gönderilen tüm öğelerin, DispatchWorkItem
irade yürütülmeden önce tamamlanması gerektiği anlamına gelir .
Kullanımı:
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let queue = DispatchQueue(label: "com.company.app.queue", attributes: .concurrent)
queue.async {
print("#1 started")
Thread.sleep(forTimeInterval: 5)
print("#1 finished")
}
queue.async {
print("#2 started")
Thread.sleep(forTimeInterval: 2)
print("#2 finished")
}
queue.async(flags: .barrier) {
print("#3 finished")
}
/*
prints:
#1 started
#2 started
#2 finished
#1 finished
#3 finished
*/
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let queue = DispatchQueue(label: "com.company.app.queue", attributes: .concurrent)
queue.async {
print("#1 started")
Thread.sleep(forTimeInterval: 5)
print("#1 finished")
}
queue.async {
print("#2 started")
Thread.sleep(forTimeInterval: 2)
print("#2 finished")
}
let dispatchWorkItem = DispatchWorkItem(qos: .default, flags: .barrier) {
print("#3 finished")
}
queue.async(execute: dispatchWorkItem)
/*
prints:
#1 started
#2 started
#2 finished
#1 finished
#3 finished
*/
5.. Kullanılıyor DispatchSemaphore
, DispatchSemaphore
'swait()
ve DispatchSemaphore
' lersignal()
Soroush Khanlou, GCD El Kitabı blog yazısına şu satırları yazdı :
Bir semafor kullanarak, bir iş parçacığını başka bir iş parçacığından gelen sinyal gönderilinceye kadar rastgele bir süre engelleyebiliriz. Semaforlar, GCD'nin geri kalanı gibi, iplik korumalıdır ve her yerden tetiklenebilirler. Semaforlar, senkronize etmeniz gereken asenkronize bir API olduğunda kullanılabilir, ancak değiştiremezsiniz.
Apple Developer API Reference ayrıca şu tartışmayı da sunar: DispatchSemaphore
init(value:)
başlatıcı :
Değer için sıfır iletmek, iki iş parçacığının belirli bir olayın tamamlanmasını uzlaştırması gerektiğinde yararlıdır. Sıfırdan büyük bir değer iletmek, havuz boyutunun değere eşit olduğu sınırlı bir kaynak havuzunu yönetmek için kullanışlıdır.
Kullanımı:
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let queue = DispatchQueue(label: "com.company.app.queue", attributes: .concurrent)
let semaphore = DispatchSemaphore(value: 0)
queue.async {
print("#1 started")
Thread.sleep(forTimeInterval: 5)
print("#1 finished")
semaphore.signal()
}
queue.async {
print("#2 started")
Thread.sleep(forTimeInterval: 2)
print("#2 finished")
semaphore.signal()
}
queue.async {
semaphore.wait()
semaphore.wait()
print("#3 finished")
}
/*
prints:
#1 started
#2 started
#2 finished
#1 finished
#3 finished
*/
Apple Developer API Referansı hakkında OperationQueue
:
İşlem kuyrukları libdispatch
, işlemlerinin yürütülmesini başlatmak kütüphaneyi (Grand Central Dispatch olarak da bilinir) kullanır.
Kullanımı:
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let operationQueue = OperationQueue()
let blockOne = BlockOperation {
print("#1 started")
Thread.sleep(forTimeInterval: 5)
print("#1 finished")
}
let blockTwo = BlockOperation {
print("#2 started")
Thread.sleep(forTimeInterval: 2)
print("#2 finished")
}
let blockThree = BlockOperation {
print("#3 finished")
}
blockThree.addDependency(blockOne)
blockThree.addDependency(blockTwo)
operationQueue.addOperations([blockThree, blockTwo, blockOne], waitUntilFinished: false)
/*
prints:
#1 started
#2 started
#2 finished
#1 finished
#3 finished
or
#2 started
#1 started
#2 finished
#1 finished
#3 finished
*/
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let operationQueue = OperationQueue()
let blockOne = BlockOperation {
print("#1 started")
Thread.sleep(forTimeInterval: 5)
print("#1 finished")
}
let blockTwo = BlockOperation {
print("#2 started")
Thread.sleep(forTimeInterval: 2)
print("#2 finished")
}
operationQueue.addOperations([blockTwo, blockOne], waitUntilFinished: false)
operationQueue.addBarrierBlock {
print("#3 finished")
}
/*
prints:
#1 started
#2 started
#2 finished
#1 finished
#3 finished
or
#2 started
#1 started
#2 finished
#1 finished
#3 finished
*/