Dengan Swift 5.1, Grand Central Dispatch menawarkan banyak cara untuk menyelesaikan masalah Anda. Sesuai dengan kebutuhan Anda, Anda dapat memilih salah satu dari tujuh pola yang ditunjukkan dalam cuplikan Playground berikut.
Panduan Pemrograman Concurrency Pengembang Apple menyatakan tentangDispatchGroup
:
Grup pengiriman adalah cara untuk memblokir utas sampai satu atau lebih tugas selesai dieksekusi. Anda dapat menggunakan perilaku ini di tempat-tempat di mana Anda tidak dapat membuat kemajuan sampai semua tugas yang ditentukan selesai. Misalnya, setelah mengirim beberapa tugas untuk menghitung beberapa data, Anda mungkin menggunakan grup untuk menunggu tugas-tugas itu dan kemudian memproses hasilnya ketika selesai.
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. Menggunakan DispatchGroup
, DispatchGroup
's wait()
, DispatchGroup
' enter()
dan DispatchGroup
'leave()
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
*/
Perhatikan bahwa Anda juga dapat bergaul DispatchGroup
wait()
dengan DispatchQueue
async(group:qos:flags:execute:)
atau menggabungkan DispatchGroup
enter()
dan DispatchGroup
leave()
dengan DispatchGroup
notify(qos:flags:queue:execute:)
.
Tutorial Grand Central Dispatch untuk Swift 4: Bagian 1/2 artikel dari Raywenderlich.com memberikan definisi untuk hambatan :
Hambatan pengiriman adalah sekelompok fungsi yang bertindak sebagai hambatan serial-style ketika bekerja dengan antrian bersamaan. Ketika Anda mengirimkan DispatchWorkItem
ke antrian pengiriman, Anda dapat mengatur bendera untuk menunjukkan bahwa itu harus menjadi satu-satunya item yang dieksekusi pada antrian yang ditentukan untuk waktu tertentu. Ini berarti bahwa semua item yang dikirim ke antrian sebelum penghalang pengiriman harus diselesaikan sebelum DispatchWorkItem
akan dieksekusi.
Pemakaian:
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
*/
Soroush Khanlou menulis baris berikut dalam posting blog The GCD Handbook :
Dengan menggunakan semaphore, kita dapat memblokir utas untuk jumlah waktu yang sewenang-wenang, sampai sinyal dari utas lain dikirim. Semaphores, seperti GCD lainnya, adalah thread-safe, dan mereka dapat dipicu dari mana saja. Semaphores dapat digunakan ketika ada API asinkron yang perlu Anda sinkronkan, tetapi Anda tidak dapat memodifikasinya.
Referensi API Pengembang Apple juga memberikan diskusi berikut untuk DispatchSemaphore
init(value:)
penginisialisasi:
Melewati nol untuk nilai berguna saat dua utas perlu merekonsiliasi penyelesaian acara tertentu. Melewati nilai yang lebih besar dari nol berguna untuk mengelola kumpulan sumber daya yang terbatas, di mana ukuran kumpulan sama dengan nilai.
Pemakaian:
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
*/
Referensi API Pengembang Apple menyatakan tentang OperationQueue
:
Antrian operasi menggunakan libdispatch
perpustakaan (juga dikenal sebagai Grand Central Dispatch) untuk memulai pelaksanaan operasi mereka.
Pemakaian:
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
*/