1. Race Condition
- 여러개의 스레드를 사용하는 환경에서 코드가 동시에 실행되어 하나의 값에 동시에 접근하는 경우가 발생
var cards = [1, 2, 3, 4, 5, 6, 7, 8, 9]
DispatchQueue.global().async {
for _ in 1...3 {
let card = cards.removeFirst()
print("지민: \(card) 카드를 뽑았습니다!")
}
}
DispatchQueue.global().async {
for _ in 1...3 {
let card = cards.removeFirst()
print("민정: \(card) 카드를 뽑았습니다!")
}
}
DispatchQueue.global().async {
for _ in 1...3 {
let card = cards.removeFirst()
print("카리나: \(card) 카드를 뽑았습니다!")
}
}
- card 배열은 1이 하나만 존재하는데 여러개의 카드를 선택
2. Thread Safe
- Race Condition의 발생하는 이유는 스위프트가 Thread Safe하지 않다는 것
- Thread Safe하다는 것은 여러 스레드에서 동시에 접근이 불가능 한 것을 말함
3. DispatchSemaphore
- Race Condtion를 해결하기 위한 수단 중 하나
- 공유 자원에 접근할 수 있는 스레드의 수를 제어해주는 역할
- DispatchSemaphore는 semaphore count를 카운트 하는 방식으로 동작
let semaphore = DispatchSemaphore(value: 1)
DispatchQueue.global().async {
semaphore.wait()
semaphore.signal()
}
var cards = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let semaphore = DispatchSemaphore(value: 1)
DispatchQueue.global().async {
for _ in 1...3 {
semaphore.wait()
let card = cards.removeFirst()
print("지민: \(card) 카드를 뽑았습니다!")
semaphore.signal()
}
}
DispatchQueue.global().async {
for _ in 1...3 {
semaphore.wait()
let card = cards.removeFirst()
print("민정: \(card) 카드를 뽑았습니다!")
semaphore.signal()
}
}
DispatchQueue.global().async {
for _ in 1...3 {
semaphore.wait()
let card = cards.removeFirst()
print("카리나: \(card) 카드를 뽑았습니다!")
semaphore.signal()
}
}
4. Serial Queue 활용
- Race Condition 발생이유 -> 여러 스레드에서 질서없이 배열에 접근
- 질서를 Serial Queue로 만드는 방식
var cards = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let pickCardsSerialQueue = DispatchQueue(label: "PickCardsQueue")
DispatchQueue.global().async {
for _ in 1...3 {
pickCardsSerialQueue.sync {
let card = cards.removeFirst()
print("지민: \(card) 카드를 뽑았습니다!")
}
}
}
DispatchQueue.global().async {
for _ in 1...3 {
pickCardsSerialQueue.sync {
let card = cards.removeFirst()
print("민정: \(card) 카드를 뽑았습니다!")
}
}
}
DispatchQueue.global().async {
for _ in 1...3 {
pickCardsSerialQueue.sync {
let card = cards.removeFirst()
print("카리나: \(card) 카드를 뽑았습니다!")
}
}
}