본문 바로가기

iOS

[동시성 프로그래밍] GCD - 작업을 큐로 보낸다. / GCD vs Operation

728x90

https://www.inflearn.com/course/iOS-Concurrency-GCD-Operation/

 

iOS Concurrency(동시성) 프로그래밍, 동기 비동기 처리 그리고 GCD/Operation - 디스패치큐와 오퍼레이션

동시성(Concurrency)프로그래밍 - iOS프로그래밍에서 필요한 동기, 비동기의 개념 및 그를 확장한 GCD 및 Operation에 관한 모든 내용을 다룹니다., - 강의 소개 | 인프런...

www.inflearn.com

위 강의를 듣고 정리한 글입니다.


노동자에게 일을 분배해보자

  • 컴퓨터에는 여러 노동자가 있고, 이 노동자에게 일을 분배해서 작업을 진행한다.
  • 여기서 노동자 = 쓰레드 / 일 = 테스크라고 보면 된다.

 

메인 쓰레드

  • 메인 쓰레드는 하나만 존재한다.
  • 대표적인 작업 중 하나는 UI를 그리는 일이다.
  • 코드를 작성할 때 별도의 처리를 하지 않았다면 메인 쓰레드가 모든 테스크를 관리한다.

 

왜 UI를 메인 쓰레드에서 다루는가?
  • UIKit의 모든 속성을 Thread-Safe하게 설게하면 성능저하(느려짐)가 발생할 수 있기 때문이다.
  • 메인 런루프가 뷰의 업데이트를 관리하는 View Drawing Cycle을 통해 동작하는 메인 쓰레드가 아닌 백그라운드 쓰레드가 각자의 런루프로 동작을 하게 되면 뷰가 제멋대로 동작할 수 있다.
  • OS가 그림의 그리는 **렌더링 프로세스(코어애니메이션 -> 렌더서버 -> GPU -> 표시)**가 있는데, 여러 쓰레드에서 각자의 뷰의 변경사항 GPU로 보내면 GPU는 각각의 정보를 다 해석해야하니 느려지거나, 비효율적이 될 수 있다.
  • Texture나 ComponentKit이라는 페이스북에서 개발한 비동기적 UI 프레임워크가 있긴 하지만, View Drawing Cycle가 유사한 방식으로 **적절한 타이밍에 메인 쓰레드에서 동시에 업데이트** 하도록 하고 있다.

 

왜 버벅거리게 되는가?
  • print, 단순 계산은 금방할 수 있지만 네트워킹(이미지 다운로드)과 같은 시간이 오래 걸리는 작업의 경우에는 뷰를 그리는 것에 온전히 집중할 수 없을만큼 무거운 작업들이 있기 때문이다.

 

일을 나눠보자.

  • 메인 쓰레드에 몰린 작업들을 다른 쓰레드에서도 동시에 작업하도록 하는 것이 동시성 프로그래밍이다.
    • 일을 나눌 때 주의할 점은 일을 잘 나눠야 한다는 것이다.
    • 다행히도, iOS에서는 작업을 한 곳에 보내기만 하면 알아서 OS가 다른 쓰레드로 분산 처리를 한다.
  • 이 일을 하는 곳이 바로 Queue(대기 행렬)이다.
    • Queue의 특징인 선입 선출로 일이 나가게 된다.
    • 그러므로 개발자가 할 일은 작업을 큐로 보내는 것이다.

 

GCD vs Operation

  • 메인 쓰레드에 몰린 Task를 Queue에 보내기만 하면 다른 쓰레드를 적절하게 생성하여 분배한다.
  • 그리고 이러한 다수의 쓰레드에게 적절히 일을 분해시켜 동작하도록 하는 동시성 프로그래밍을 위해 iOS에서 지원하는 기술들이 존재한다.

 

GCD (Grand Central Dispatch)

  • GCD는 우리가 Queue에 작업을 보내면 그에 따른 스레드를 적절히 생성해서 분배해주는 첫번째 방법이다.
  • GCD에서 사용하는 Queue의 이름이 Dispatch Queue이다.
  • Dispatch Queue에 작업을 추가하면 GCD는 작업에 맞는 쓰레드를 자동으로 생성하여 Task를 실행하고 작업을 다 종료하면 Thread를 제거하게 된다.

 

DispatchQueue.global().async {
  //task
}

코드로 작성하면 위와 같이 나타낼 수 있다.

  • DispatchQueue : iOS에서 동시성 프로그래밍을 돕기 위해 제공하는 큐
  • global : Dispatch Queue의 종류 (main/global)
  • async : 비동기

→ 즉, 한글로 코드를 해석해보면 : global dispatch queue에 비동기로 task를 보낸다

  • 클로저 구문의 코드 블럭이 작업의 한 단위를 의미한다.
  • 클로저 내의 Task는 하나의 작업이기 때문에 그 안의 동작들은 순차적으로 처리가 된다.

 

Operation

  • Operation도 GCD와 같이 쓰레드를 적절하게 생성하여 분배하는 방법 중 하나로
  • Operation에서 사용하는 큐의 이름은 Operation Queue라고 한다.
  • 내부적으로는 GCD 위에서 동작하나, 좀 더 기능이 추가된 형태이다.
  • 동시에 실행할 수 있는 동작의 최대 수를 지정할 수 있고
  • 동작 일시 중지 및 취소를 할 수 있다.
  • Operation이 좀 더 기능이 많고 좋아보일 수 있지만 구현이 좀 더 복잡할 수 있기 때문에 무조건적으로 무엇이 더 좋다고 할 수 없다. (뭘 써야 한다!고 정해진 것은 딱히 없고 그 때 상황에 맞게 적절한 것을 사용하면 된다.)