본문 바로가기

iOS

[iOS]동시성 프로그래밍, GCD, 동기, 비동기, 직렬성

동시성 프로그래밍 concurrency

- 다수의 스레드에 적절히 일을 분배 시켜서 동장 하도록 하는 프로그래밍

 

 

주로 iOS에서는 메인 스레드로 UI를 그리는 작업을 하고 이미지를 다운로드 받아오는 등 큰 데이터를 쓰는 작업은 비동기로 다른 스레드에서 처리하게 됩니다. 이렇게 여러 스레드를 사용해서 iOS에서는 동시성 프로그래밍이 가능합니다.

 

다른 스레드로 task를 보내기전 선입선출을 하는 queue에 task를 저장합니다. 그리고 이 queue에서 여러개의 다른 스레드로 task를 보내어 처리를 해줍니다. 이렇게 queue에 있는 task들을 여러 스레드로 분산처리 해주는 것이 바로 GCD입니다.

 

GCD (Grand Central Dispatch)

queue에 넣은 작업을 GCD가 스레드를 적절히 생성해서 분배해준다. 작업종료시 제거까지 해준다.

 

GCD에서 관리하는 queue 이름은 DispatchQueue입니다.

(dispatch = 보내다, 파견, 발송; taskQueue를 보내라! )

 

 

DispatchQueue

 

 

이렇게 씁니다.!! 

 

DispatchQueue : iOS에서 동시성 프로그래밍을 돕기 위해 제공하는 queue

global :  DispatchQueue의 종류

async :  비동기

 

해석하자면 "global dispatch queue에 비동기로 task를 보낸다.!!" 

 

 

 

GCD는 우리가 Queue에 작업을 보내면 그에 따른 스레드를 적절히 생성해서 분배해주는 첫 번째 방법입니다.

그리고 두번째 방법인 Operation이 있는데 간단하게 설명만 하겠습니다.

 

+ Operation

 Operation에서 사용하는 queue의 이름은 Operation Queue입니다. Operation은 GCD 위에서 동작을 하지만 기능들이 조금 더 추가된 형태입니다.

 

- 동시에 실행할 수 있는 동작의 최대 수 지정

- 동작 일시 중지 및 취소

 

기능들이 더 추가된 만큼 약간 더 복잡하기 때문에 OperationQueue와 DispatchQueue는 상황에 따라 적절히 써줘야 합니다. 

 

저는 일단 DispatchQueue에 관한 것만 다루겠습니다!

 

 

 

 

 

앞에서 DispatchQueue를 설명하면서 "global dispatch queue에 비동기로 task를 보낸다.!!"라고 했는데요. 이제 동기와 비동기를 알아보겠습니다.

sync(동기)와 async(비동기)

 

메인 스레드에서 DispatchQueue에 일을 보낸뒤에

결과를 기다리고 메인스레드의 일을 할지 = sync

결과를 기다리지 않고 메인스레드의 일을 할지 = async

 

이게 바로 동기 비동기의 개념입니다.

 

예시로 볼까요!!!

각각의 queue에 sleep을 넣었습니다. 결과가 어떻게 될까요?!?!

 

 

바로!! 그냥 sleep을 줬지만 바로 뜹니다.!!! 

(니 할일 내 할일 따로 처리하겠다.!! 이게 비동기다.!)

 

 

 

동기와 비동기 예시의 자리를 바꿔볼까요!

 

 

출력 값은?!?!?!

 

 

3초후

.

.

.

 

동기가 뜨고 3초후에 비동기 task가 뜹니다.

(sync로 보내게되면 너가 일 끝나는거 기다렸다가 내 할일 할래!! 같은 느낌입니다.)

 

 

global(), main()

앞에 DispatchQueue.global() 이라는 것을 보셨겠죠?!! 

global()은 무엇인가.. 설명 해드리겠습니다.!!

 

큐의 특성에 따라 Serial(직렬)특성, Concurrent(동시)특성을 가집니다.

 

- Serial은 분산처리 시킨 작업을 한개의 스레드에서 처리하게 됩니다.

- Concurrent(동시)는 GCD or Operation이 여러 스레드로 나눠서 처리합니다.

 

 

그렇다면 적재적소에 어떤 특성의 큐를 사용할까!! 

 

Serail

- 작업들이 이전 작업을 끝내고 실행해야하는 경우 순서대로 작업을 실행시킬때 (작업 순서가 중요한 경우)

 

Concurrent

- 큐는 여러개의 스레드로 분배되서 실행되서 각각의 작업들이 언제 끝나는지 알 수 없음.

- 큐에서 나올 때는 선입 선출이지만 끝나는건 작업량이 작은애가 제일 먼저 끝남.

- 이 예는 cell에서 이미지로드할때 이미지가 어떤 셀에 먼저 들어갈지 순서가 상관없음 그냥 빠르게 되면 좋은거 그런경우 concurrent queue 사용.

 

 

참고

 

[iOS] 차근차근 시작하는 GCD — 1

이번엔 제발 이해하고 싶다 GCD..🥂

sujinnaljin.medium.com

 

후기

저는 동기/ 비동기 개념보다.. 파일 크기가 큰 파일을 가져올 때, URLSession에서 API 통신을 할 때, animate()를 쓸 때의 상황을 먼저 겪었습니다.

메인 문에서 파일 크기가 큰 파일을 가져올 때 UI가 많이 버벅거렸고.. 멈칫 멈칫..

API통신을 할때는 그냥 되니까 썼는데 사실 URLSession자체가 비동기로 만들어진.. 객체였고..

animate()도 블로깅하면서 뭐지 저거 어떻게 동작하는거지 했는데 아아 역시 이또한 비동기로 만들어진 메서드

 

또 마주친42앱에 비동기로 각각 돌리고 별도의 플래그를 만들어서 체크하면서 모든 비동기 작업들이 완료되면 다음 작업을 실행하게 했는데...이 또한 이미 세마포어나 그룹으로 관리를 할 수 있다는 것을 공부 중 알았습니다.  ㅎㅎ 이어서 바로 블로깅 하겠습니다.

 

'iOS' 카테고리의 다른 글

[iOS] DispatchGroup, DispatchItem, DispatchSemaphore  (0) 2021.04.10
[iOS] Dispatch Queue 종류  (0) 2021.04.10
[iOS] updateCycle  (0) 2021.04.07
[iOS] RunLoop  (0) 2021.04.07
[iOS] animate - layout, setNeedsLayout, layoutIfNeeded  (0) 2021.04.05