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 카드를 뽑았습니다!
*/

Serial Queue 활용하여 race condition 해결하기

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 카드를 뽑았습니다!
*/