Swift/非同期処理
表示
< Swift
非同期処理
[編集]DispatchQueue
[編集]import Dispatch
let NMAX = 100
DispatchQueue.global(priority: .low).async {
var n = 1.0
var e = 1.0
for i in 1...NMAX {
n *= Double(i)
e += 1.0 / n
print("e(\(i)) = \(e)")
}
}
DispatchQueue.global(priority: .low).async {
var pm = -1.0
var pi = 0.0
for i in 0...NMAX {
pm *= -1
pi += pm * 4 / (2 * Double(i) + 1)
print("pi(\(i)) = \(pi)")
}
}
遅延実行
[編集]import Dispatch
let semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global(priority: .low).async { // すぐに実行
print("executed now")
semaphore.signal()
}
semaphore.wait()
DispatchQueue.global(priority: .low).asyncAfter(deadline: .now() + 1) { // 1秒後に実行
print("executed 1 second later")
semaphore.signal()
}
semaphore.wait()
DispatchGroup
[編集]import Dispatch
let NMAX = 10000
let group = DispatchGroup()
let queue1 = DispatchQueue.global(priority: .low)
queue1.async(group: group) {
var n = 1.0
var e = 1.0
for i in 1...NMAX {
n *= Double(i)
e += 1.0 / n
print("e(\(i)) = \(e)")
}
}
let queue2 = DispatchQueue.global(priority: .low)
queue2.async(group: group) {
var pm = -1.0
var pi = 0.0
for i in 0...NMAX {
pm *= -1
pi += pm * 4 / (2 * Double(i) + 1)
print("pi(\(i)) = \(pi)")
}
}
group.wait()
print("queue finished")
DispatchSemaphore
[編集]import Dispatch
let NMAX = 10000
let semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global(priority: .low).async {
for i in 0..<NMAX {
print(i)
}
semaphore.signal()
}
print("before waiting")
semaphore.wait() // この1行を外すと、NMAXまで出力される前に次の行に進む
print("after waiting")
async/await (Swift 5.5以降)
[編集]Swift 5.7以降(Task.sleep使用可能)
import Foundation
let semaphore2 = DispatchSemaphore(value: 0)
func asyncTaskCore(n:Int) async {
try! await Task.sleep(for: .seconds(1))
print("asyncTaskCore(\(n)) done")
}
func asyncTask() async {
await asyncTaskCore(n: 0) // コールバック関数の場合との比較のため、あえてfor文不使用
await asyncTaskCore(n: 1)
await asyncTaskCore(n: 2)
await asyncTaskCore(n: 3)
await asyncTaskCore(n: 4)
}
Task {
await asyncTask()
semaphore2.signal()
}
semaphore2.wait()
Swift 5.5.x~5.6.x
import Foundation
let semaphore2 = DispatchSemaphore(value: 0)
func asyncTaskCore(n:Int) async {
let semaphore1 = DispatchSemaphore(value: 0)
DispatchQueue.global(priority: .low).asyncAfter(deadline: .now() + 1) {
semaphore1.signal()
}
semaphore1.wait()
print("asyncTaskCore(\(n)) done")
}
func asyncTask() async {
await asyncTaskCore(n: 0)
await asyncTaskCore(n: 1)
await asyncTaskCore(n: 2)
await asyncTaskCore(n: 3)
await asyncTaskCore(n: 4)
}
Task {
await asyncTask()
semaphore2.signal()
}
semaphore2.wait()
Swift 5.4.x以前(コールバック関数使用)
import Foundation
let semaphore2 = DispatchSemaphore(value: 0)
func asyncTaskCore(n:Int, callback:() -> ()) {
let semaphore1 = DispatchSemaphore(value: 0)
DispatchQueue.global(priority: .low).asyncAfter(deadline: .now() + 1) {
semaphore1.signal()
}
semaphore1.wait()
print("asyncTaskCore(\(n)) done")
callback()
}
func asyncTask(callback:@escaping () -> ()) {
asyncTaskCore(n: 0, callback: {
asyncTaskCore(n: 1, callback: {
asyncTaskCore(n: 2, callback: {
asyncTaskCore(n: 3, callback: {
asyncTaskCore(n: 4, callback: {
callback()
})
})
})
})
})
}
asyncTask(callback: {
semaphore2.signal()
})
semaphore2.wait()