Swift Concurrency
1. GCD
2. OperationQueue : 내부적으로 GCD 기반으로 이루어져 있음
3. Async/Await : iOS15~ 나온 새로운 기술
비동기를 위한 아이덜~
serial/Main + Sync
serial/Main + Async
concurrency/Global + Sync
concurrency/Global + Async
Global Quality of Service - QoS
DispatchGroup - 동기
DispatchGroup - 비동기
경쟁상태
요약
코드 참고 : https://github.com/heerucan/iOS-Begin-Again/commit/9a9e19fd71746fb2c1f49c8441dd4a9f72cb6791
🚫 1. Serial/Main + Sync
🚫🚫🚫🚫해당 코드는 절대 앞으로 쓰면 안되고, 쓸 일이 없다!🚫🚫🚫🚫
1. 작업 분배하기 귀찮으니 하나의 스레드로 몰아버림 - Main Thread로 몰아버림
But, 현재의 큐에서 현재의 큐로 동기적으로 보내면 안된다 -> 무한대기상태 = 교착상태 = Deadlock
즉, Main이 101~200 들어가기 전까지 기다리는 상태인데
동시에 Main이 일해야 하는데 + Main이 한도 끝도 없이 기다려서 충돌이 발생하는 상태
2.Serial/Main + Async UI 변경 때 사용
2-1. 1개의 테스크가 Queue를 통해 Main Thread로 보내진 것
1번이랑 다른 거는 Queue에게 보내고 나서 기다리지 않고 바로 다음 작업을 실행한다.
그리고 보내놨던 코드를 실행한다. 결국, 보내놓은 코드가 Main -> Main Thread 이긴 함
1~100을 async로 보낸다.
보내고 바로 다음 작업을 시작한다.
- 101~200 출력
- End 출력
보내놨던 코드를 다시 실행
2-2. 100개의 테스크가 Queue를 통해 Main Thread로 보내진 것
🚫 3. Concurrency/Global + Sync
🚫🚫🚫🚫해당 코드는 써봤자 의미없기에 쓸 일이 없다!🚫🚫🚫🚫
Queue에게 보낸 후 다른 Thread(알바생)한테 작업을 보냄
근데 sync라서 Queue에 있는 작업이 끝날 때까지 다음 작업은 기다리는 거라 아래와 같이 출력
닭벼슬(Main Thread)은 덜 힘들지만, 결국 의미없는 일임
Main Thread에서 동작하는 거랑 유사하네?
왜 유사하냐?
결국,, 닭벼슬(Main Thread)의 일을 매니저(큐)를 통해서 보내, 다른 알바한테
그치만 닯벼슬(Main Thread)이 보내고 나서
알바A가 커피 만들고 -> 알바B가 A커피 다 만들어지면 빙수 만들고, -> 알바C는 B빙수 끝나면 허니브레드 만드는 것임
즉, 닭벼슬(Main Thread)이 커피 만들고 나서 빙수 만들고, 허니브레드 만드는 것이랑 별 다를게 없음
알바생이 늘어나서 닭벼슬(Main Thread)은 편하겟지만,,,, 알바A, B, C 이럴거면 왜 돈주고 쓰냐? 이말임
그래서 의미없는 짓이라고 판단해서 애플은 내부적으로 다른 Thread로 넘기지 않고, Main Thread에서 작업을 진행한다.
즉, 이 코드는 우리가 앞으로 쓸 일이 없다.
4. Concurrency/Global + Async 네트워크 사용에 쓰고
4-1. 1개의 task를 다른 Thread(알바생)한테 해달라고 Queue를 통해 비동기적으로 보냄
2번이랑 다른 거는 보내놓은 코드가 Main -> Global Thread
다른 알바생한테 해달라고 async를 통해 보냄
보내자마자 닭벼슬은 자기 일하고, 받은 강아지는 또 자기 일 바로 시작해서
뒤죽박죽으로 섞인 것임
동시에 자기 일을 처리하고,
- 보낸 후에 안 기다리고 바로 시작 + 받은 후 바로 일 시작
즉, 카페에 알바생이 여럿 있는데 동시에 주문 받고 동시에 일 처리하는 바이브
알바생으로서 제몫을 다 한다고 보면 됨
사장 돈이 아깝지 않다 이거임
4-2. 100개의 task를 다른 Thread(알바생)한테 해달라고 Queue를 통해 비동기적으로 보냄
100개의 일을 다 뿌려서 여기저기에 섞여서 출력
🔆 MainThread인지 출력을 받아보자
🔆 출력 할 때마다 다른 결과값이 나옴
어떤 Thread가 먼저 일할지 몰라서 그런 것임
신기해서 가져와봄
Global Quality of Service - QoS
맥딜리버리에서 주문할 때 아이스크림도 같이 시키면 빨리옴 댕꿀?
녹기 쉬운 음식이 배달되는 건 다른 것보다 더 중요해, 더 빨리 ㄱ 해야 돼!
중요한 일에 boost 달아주기 = QoS
qos 우선순위 순서 : userInteractive- userInitiated - default - utility - background - unspecified
🔆 userInteractive
사용자와 인터렉션이 있는 작업이 우선순위가 제일 높음
왜? 한국인은 못 기다려. 빨랑빨랑 해줘야 됨
그리고 OS가 QoS를 굳이 설정 안해도 알아서 작업의 서비스 품질을 추론함
100개의 작업을 따로 보내는 바이브
우선순위에 따라서 userInteractive - utility - background 순으로 끝나긴 함
DispatchGroup
왜 위 코드가 이렇게 드러웠나!?
Cuz, 끝나는 시점을 명확히 알아야 테이블뷰의 갱신이 가능하기 때문에 이렇게 작성해줬음
근데 비동기라서 언제 끝나는지 잘 몰라
여러개의 비동기 코드가 있으면 유추하기 어렵고 힘들다.
가장 나중에 끝나는 친구한테 갱신코드를 작성해주면 되는데 네트워크 상태에 따라서 다른 스레드가 늦게 끝날 수 있음
즉, 명확하게 누가 먼저 끝나는지 확실치 않아!
그렇다면, 여러개의 테스크를 하나의 그룹으로 묶어서 "나 끝났어"를 신호로 받는 것 = DispatchGroup
DispatchGroup을 사용하면?
1). group내의 작업들이 동기적인 경우!!!!! async에 들어있지만 내부 작업이 동기적으로 작업함
group을 만들고, notify를 통해서 마지막 출력이 된 것을 확인하고, 갱신코드를 클로저 내부에 작성!
2). group내의 작업들이 비동기적인 경우, 예를 들어 네트워크 작업들 - urlsession은 global 큐에서 비동기동작 코드임
근데 비동기 코드를 DispatchGroup으로 묶어줄 수 있는데
group 내에서 있는 네트워크 코드는 비동기로 작동하기 때문에
바깥 비동기와 내부 비동기는 또 서로 다른 스레드(즉, 외부 알바생과 내부 알바생은 또 별개란 것)에서 작업을 한다.
= 탈주 vibe, 외주 vibe, 지멋대로지맘대로 vibe
그래서 끝나는 지점을 체크하기 어렵다.
어떻게 해결해주나? enter(), leave()
enter, leave를 각 비동기 코드 앞 뒤에 짝을 맞춰서 달아주면 된다.
enter -> RC +1
leave -> RC -1
Reference Count는 차차 알아보쟈.
만약 enter/leave를 사용하지 않으면
Race Condition 경쟁상태
같은 공유자원에 2번, 3번~ 접근할 경우에 경쟁상태가 발생할 수 있다고 말하게 됨
정교빈 내거임 이런 바이브.
🛟 정리하자면
1. serial, main / sync : 메인 -> 메인, 기다림 = 교착상태 🚫
2. serial, main / async : 메인 -> 메인, 안기다림 - UI 변경 때 사용
3. concurrency, global / sync : 메인 -> 글로벌, 기다림 = 의미없음 (1번이랑 같음) 🚫
4. concurrency, global / async : 메인 -> 글로벌, 안기다림 - 네트워크 사용에 쓰고
Queue : 작업을 전달 받아 다른 스레드에게 분배해주는 매니저 역할
- Main
- Global
- Custom으로 만들 수도 있음!
DispatchGroup
여러개의 async 비동기 처리 코드가 있을 경우, 끝나는 시점을 명확하게 파악할 수 없다.
그렇다면 DispatchGroup을 통해서 각각의 스레드를 묶어서 끝날 때 신호를 받게 하자!
notify를 통해서 끝난 시점을 알면 그 후 갱신코드를 갈기면 된다.
근데 고려해야 할 것은
1). 그룹 내 작업들이 동기적인 경우
2). 그룹 내 작업들이 비동기(네트워크)적인 경우 - enter, leave 표기!
으아 댕어렵다; ㅋ.... 후. 헷갈리고.. 매일매일 읽어야 할 것 같다.
요놈.. GCD inflearn 강의에서 듣고 수업 때 들으니 그래도 처음 듣는 개념이 아니라 받아들이기 쉬웠지만
코드를 보고 실행하기 전까지 이게 어떻게 돌아가겠구나를 바로 알지 못하겠다..ㅠ
아모튼! 여러번 반복해서 학습하자... ㅍㅇㅌ ㅍㅇㅌ 포기금지 이제 여기서 포기하면 백수
'⭐️ 개발 > iOS Concurrency' 카테고리의 다른 글
[GCD] Dispatch Group (4) | 2022.08.29 |
---|---|
[GCD] weak self (1) | 2022.08.20 |
[GCD] 섹션 1~3 요약정리 (3) | 2022.08.18 |