훌이
후리스콜링개발
훌이

블로그 메뉴

  • 왈 (iOS APP)
  • Github
전체 방문자
오늘
어제
  • 전체 (171)
    • ⭐️ 개발 (140)
      • JAVA (4)
      • Web (5)
      • iOS & Swift (94)
      • iOS Concurrency (4)
      • Rx (18)
      • Git (6)
      • WWDC (1)
      • Code Refactor (3)
      • Server (1)
    • ⭐️ Computer Science (22)
      • 운영체제 (10)
      • 네트워크 (5)
      • PS (7)
    • 경제시사상식 (8)
    • 기타 등등 (0)

인기 글

최근 글

05-18 10:50

티스토리

hELLO · Designed By 정상우.
훌이

후리스콜링개발

[GCD] Swift Concurrency - GCD
⭐️ 개발/iOS Concurrency

[GCD] Swift Concurrency - GCD

2022. 9. 2. 13:09
728x90
반응형

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

그래서 끝나는 지점을 체크하기 어렵다.

 

 

thx to 도이님

어떻게 해결해주나? 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 강의에서 듣고 수업 때 들으니 그래도 처음 듣는 개념이 아니라 받아들이기 쉬웠지만
코드를 보고 실행하기 전까지 이게 어떻게 돌아가겠구나를 바로 알지 못하겠다..ㅠ
아모튼! 여러번 반복해서 학습하자... ㅍㅇㅌ ㅍㅇㅌ 포기금지 이제 여기서 포기하면 백수

 

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'⭐️ 개발 > iOS Concurrency' 카테고리의 다른 글

[GCD] Dispatch Group  (4) 2022.08.29
[GCD] weak self  (1) 2022.08.20
[GCD] 섹션 1~3 요약정리  (3) 2022.08.18
    '⭐️ 개발/iOS Concurrency' 카테고리의 다른 글
    • [GCD] Dispatch Group
    • [GCD] weak self
    • [GCD] 섹션 1~3 요약정리
    훌이
    훌이

    티스토리툴바