Skip to content

Instantly share code, notes, and snippets.

@boraseoksoon
Last active January 5, 2023 04:42
Show Gist options
  • Save boraseoksoon/f28859cee733265d8c128ee028dedd55 to your computer and use it in GitHub Desktop.
Save boraseoksoon/f28859cee733265d8c128ee028dedd55 to your computer and use it in GitHub Desktop.
Swift actor the most boring data race & race condition example (nonisolated)
import Foundation
class Class {
var i = 0
func decrease() {
i-=1
}
func increase() {
i+=1
}
func log() {
decrease()
increase()
print("class i : \(i)")
}
func log2() {
print("class log2")
}
func log3() {
print("class log3")
}
}
actor Actor {
var i = 0
func decrease() {
i-=1
}
func increase() {
i+=1
}
@objc nonisolated func log() {
Task {
await isolatedLog()
}
}
func isolatedLog() {
decrease()
increase()
print("actor i : \(i)")
}
@objc nonisolated func log2() {
Task {
await isolatedLog2()
}
}
func isolatedLog2() {
print("actor log2")
}
@objc nonisolated func log3() {
Task {
await isolatedLog3()
}
}
func isolatedLog3() {
print("actor log3")
}
}
let actor = Actor()
let `class` = Class()
///
///
/// Data race
///
///
DispatchQueue.concurrentPerform(iterations: 1000) { _ in
actor.log()
}
// actor i : 0
// actor i : 0
// actor i : 0
// actor i : 0
// actor i : 0
// actor i : 0
// actor i : 0
// actor i : 0
// actor i : 0
// ...
// ..
// .
// actor i : 0
DispatchQueue.concurrentPerform(iterations: 1000) { _ in
`class`.log()
}
// class i : -3
// class i : -5
// class i : -5
// class i : -2
// class i : -2
// class i : -2
// class i : -5
// class i : 0
// class i : -2
// ...
// ..
///
///
/// Race conditon
///
///
DispatchQueue.concurrentPerform(iterations: 1000) { _ in
Task {
await actor.isolatedLog2()
await actor.isolatedLog3()
}
}
// actor log2
// actor log3
// actor log2
// actor log3
// actor log2
// actor log3
// actor log2
// actor log3
// ...
// ..
// .
// actor log2
// actor log3
DispatchQueue.concurrentPerform(iterations: 1000) { _ in
actor.log2()
actor.log3()
}
// actor log2
// actor log2
// actor log2
// actor log2
// actor log2
// actor log2
// actor log2
// actor log3
// ...
DispatchQueue.concurrentPerform(iterations: 1000) { _ in
`class`.log2()
`class`.log3()
}
// class log2
// class log2
// class log2
// class log2
// class log3
// class log2
// class log3
// class log3
// class log2
// class log3
// ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment