각각의 쓰레드에서 하나의 자원에 동시 접근할때 발생하는 문제을 "경쟁 상황/경쟁 조건(Race Condition)" 또는 "Thread-Safe하지 않다" 라고 부릅니다.
2개 이상의 쓰레드에서 서로 다른 쓰레드의 작업이 끝나기만을 기다리며 작업을 더 이상 진행하지 못하는 상태를 교착 상태(Dead Lock)라 부릅니다.
경쟁 상황/경쟁 조건(Race Condition)의 해결 방법은 다양하게 존재합니다.
다양한 방법 중 가장 일반적인 방법은 동시적 접근이 아닌, 순서가 있는 직렬적인 접근을 통해 문제를 해결하는 방법입니다.
✅ 배열(자원)에 동시적으로 접근 -> 🚨 문제 발생
var array = [String]() for i in 1...20 { DispatchQueue.global().async { array.append("\(i)") // 동시다발적으로 빈 배열의 메모리에 접근하여 1~20할당 } } DispatchQueue.main.asyncAfter(deadline: .now() + 5) { //비동기적으로 1번 쓰레드에서 5초 뒤에 실행하는 코드 print(array) } /*출력 결과 ["4", "5", "6", "7", "2", "3", "1", "8", "14", "15", "16", "17", "18", "19", "20", "9", "10", "11", "12", "13"] // 8이 없음 */
✅ 배열(자원)에 직렬적으로 접근
var array = [String]() let serialQueue = DispatchQueue(label: "serial") //직렬 큐 생성 for i in 1...20 { DispatchQueue.global().async { serialQueue.async { // 직렬 방식을 사용: 하나하나 차례차례 배열의 메모리에 접근 array.append("\(i)") } } } DispatchQueue.main.asyncAfter(deadline: .now() + 5) { //비동기적으로 1번 쓰레드에서 5초 뒤에 실행하는 코드 print(array) } /*출력 결과 ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] // 모든 번호가 정상적으로 배열에 할당되었음을 확인 */