-
[Swift] GCD 사용시 주의사항과 동시성 문제들카테고리 없음 2022. 3. 15. 17:59
참고 : https://www.inflearn.com/course/iOS-Concurrency-GCD-Operation
주의할 사항
UI관련일은 메인큐에서 처리해야한다.
DispatchQueue.global().async{ task1 task2 DispatchQueue.main.async{ self.imageView.image = image } } 각기 다른스레드에서 하던일중 UI관련은 메인큐로
메인큐에서 다른 큐로 보낼때 sync 사용안됨, 항시 async
DispatchQueue.global().sync{ //이거 끝날떄까지 메인큐가 멈춰버림 } task1 task2
같은 큐로 보낼때 sync 사용안됨
DispatchQueue.global().async{ DispatchQueue.global().sync{ //같은 스레드로 보내버릴확률이 있음 그러면 교착상태발생 } task1 task2 }
동시성과 문제
2개 이상의 쓰레드를 쓰면서 동일한 메모리접근등 으로 인해 발생하는 문제
Thread-Safety : 여러쓰레드를 써도 안전하다. 한번에 한개의 쓰레드만 접근하도록 처리,
Race condition
var a = 1 DispatcQueue.global().async{ sleep(1) a += 1 } DispatcQueue.global().async{ sleep(1) a += 1 } print(a) //a가 3이길 기대하나 1이 출력됨
여러 쓰레드에서 a 를 접근하는 경쟁 상황이 발생함,
a를 제대로 쓸수없음
for (i, name) in nameList.enumertated(){ concurrentQueue.async(group:customGroup){ person.changeName() print(person.name) } }
여러 스레드에서 person 객체에 접근하여 경쟁상황이 발생한다.
어느쓰레드에서는 이름을 바꾸고
어느쓰레드에서는 같은 시간에 출력한다.
따라서 원하는 결과값이 나오지 않음.
교착상태
2개 이상 쓰레드가 2개이상 배타적인 자원 사용으로 인해
(경쟁상황을 피하기 위해 자원을 다른쓰레드에서 못쓰게할경우)
서로 점유하려하면서 사용이 막히게 되어 작업이 멈춘상태를 말함
우선순위 바뀜
낮은 우선순위 (default QOS) 에서 배타적 자원사용을 할경우 (자원을 잠그는경우) -- task1
중간 우선순위(userInitiated QOS) 에서와 -- task2
높은 우선순위 (userInteractive QOS) 에서 자원사용을 못하므로 멈추게된다. -- task3
이러면 낮은 우선순위가 먼저 재개가 되어 먼저 작업되는데 그다음 중간 우선순위가 작업된다.
기대 작업 순서는 task3 -> task2 -> task1 이지만 결과는 역순으로 작업된다.
안전한 방법은 공유된 자원을 접근할때 같은 QOS를 쓰는게 좋다.
* 하지만 GCD가 알아서 스스로 자원을 잠그고있는 default QOS의 우선순위를 (task1)
높여서(userInteractive QOS) 먼저 끝내 버리게 한다.
그후 자원 접근이 가능 해지므로 높은 우선 순위를 작업한다.
task1 -> task3 -> task2