- 데이터 읽기와 쓰기는 컴퓨터가 단일 작업으로 실행할 수 없기 때문에 서로 다른 작업으로 처리된다.
- 컴퓨터는 클럭 사이클에서 작동하며, 각 클럭 탭은 단일 작업을 실행할 수 있다.
- 클럭: 첫번째 스레드에서 값 불러오기
- 클럭: 첫번째 스레드에서 값 더하기(2), 두번째 스레드에서 값 불러오기(1)
- 클럭: 첫번째 스레드 값 저장하기(2), 두번째 스레드에서 값 더하기(2)
- 클럭: 두번째 스레드에서 값 저장하기(2)
- 즉, 이처럼 더하기 작업을 2번 실행했지만, 각 상황이 겹쳐서 더하기 작업이 이상해진것을 확인할 수 있다.
var count = 0
for _ in 0...30000 {
DispatchQueue.global().async {
count += 1
}
}
// 원래 값인 30001 아닌 엉뚱한 값이 출력됨
var count = 0
for _ in 0...30000 {
DispatchQueue.global().sync {
count += 1
}
}
// 정상적인 값을 보장받는다.
- 시리얼 큐 + Sync (엄격한 Thread-safe)
- 디스패치 베리어 작업 (조금 더 효율적인 방법)
- (추가적인, Semaphore 이용 동시실행자원도 제한 가능)
let semaphoreA = DispatchSemaphore(value: 1)
let semaphoreB = DispatchSemaphore(value: 1)
DispatchQueue.global().async {
semaphoreA.wait()
print("Thread 1: Acquired Semaphore A")
sleep(1)
semaphoreB.wait()
print("Thread 1: Acquired Semaphore B")
semaphoreB.signal()
semaphoreA.signal()
}
DispatchQueue.global().async {
semaphoreB.wait()
print("Thread 2: Acquired Semaphore B")
sleep(1)
semaphoreA.wait()
print("Thread 2: Acquired Semaphore A")
semaphoreA.signal()
semaphoreB.signal()
}
(단순한 처리 방법) 시리얼큐로 해결 가능
세마포어 등 제한된 리소스 순서 사용 / 객체 등 설계시 주의
let high = DispatchQueue.global(qos: .userInteractive)
let medium = DispatchQueue.global(qos: .userInitiated)
let low = DispatchQueue.global(qos: .background)
let semaphore = DispatchSemaphore(value: 1)
high.async {
// Wait 2 seconds just to be sure all the other tasks have enqueued
Thread.sleep(forTimeInterval: 2)
semaphore.wait()
defer { semaphore.signal() }
print("High priority task is now running")
}
for i in 1 ... 10 {
medium.async {
let waitTime = Double(exactly: arc4random_uniform(7))!
print("Running medium task \(i)")
Thread.sleep(forTimeInterval: waitTime)
}
}
low.async {
semaphore.wait()
defer { semaphore.signal() }
print("Running long, lowest priority task")
Thread.sleep(forTimeInterval: 5)
}
Running medium task 4
Running medium task 5
Running medium task 2
Running medium task 7
Running medium task 1
Running medium task 9
Running medium task 3
Running medium task 10
Running medium task 6
Running medium task 8
Running long, lowest priority task
High priority task is now running
GCD가 알아서 우선 순위 조정
(안전하게) 공유된 자원 접근시 - 동일한 QoS 사용
제가 학습한 내용을 요약하여 정리한 것입니다. 내용에 오류가 있을 수 있으며, 어떠한 피드백도 감사히 받겠습니다.
감사합니다.