class DispatchSemaphore : DispatchObject
let semaphore = DispatchSemaphore(value: 1) // count = 1
DispatchQueue.global().async {
semaphore.wait() // count -= 1
semaphore.signal() // count += 1
}
NOTE
DispatchSemaphore 사용시 주의 사항
반드시 wait()와 signal()을 짝지어서 호출해주어야 함
import Foundation
var cards = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let semaphore = DispatchSemaphore(value: 1)
DispatchQueue.global().async {
for _ in 1...2 {
semaphore.wait()
let card = cards.removeFirst()
print("데릭: \\(card) 카드를 뽑았습니다!")
semaphore.signal()
}
}
DispatchQueue.global().async {
for _ in 1...2 {
semaphore.wait()
let card = cards.removeFirst()
print("백곰: \\(card) 카드를 뽑았습니다!")
semaphore.signal()
}
}
DispatchQueue.global().async {
for _ in 1...2 {
semaphore.wait()
let card = cards.removeFirst()
print("휴: \\(card) 카드를 뽑았습니다!")
semaphore.signal()
}
}
DispatchQueue.global().async {
for _ in 1...2 {
semaphore.wait()
let card = cards.removeFirst()
print("핀: \\(card) 카드를 뽑았습니다!")
semaphore.signal()
}
}
/*
데릭: 1 카드를 뽑았습니다!
백곰: 2 카드를 뽑았습니다!
데릭: 1 카드를 뽑았습니다!
데릭: 1 카드를 뽑았습니다!
백곰: 2 카드를 뽑았습니다!
휴: 3 카드를 뽑았습니다!
핀: 4 카드를 뽑았습니다!
데릭: 5 카드를 뽑았습니다!
백곰: 6 카드를 뽑았습니다!
휴: 7 카드를 뽑았습니다!
핀: 8 카드를 뽑았습니다!
*/
cards
에 접근하기 전과 후에 semaphore의 wait()
과 signal()
을 호출해주어 다른 스레드의 접근을 막아주고 있는 것임질서
를 만들어주면 이 문제를 해결import Foundation
var cards = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let pickCardsSerialQueue = DispatchQueue(label: "PickCardsQueue")
DispatchQueue.global().async {
for _ in 1...3 {
c.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) 카드를 뽑았습니다!")
}
}
}
/*
야곰: 1 카드를 뽑았습니다!
노루: 2 카드를 뽑았습니다!
오동나무: 3 카드를 뽑았습니다!
*/