본문 바로가기
Study

[iOS Concurrency] 나야.. 동시성. (feat. 흑백요리사)

by 차코.. 2024. 10. 10.

💭 동시성 프로그래밍, 왜 필요할까?

 

 

개발을 하다보면 '동시성'이라는 개념을 자주 접하게 되는데요.

 

동시성은 단어 그대로, '동시'에 작업을 시키기 때문에

시스템의 성능 향상반응성을 개선해 줄 수 있습니다.

 

 

 

동시성 프로그래밍을 사용하지 않는다면 어떻게 될까요?

 

핀터레스트를 예를 들어봅시다.

 

많은 양의 사진이 존재하는 핀터레스트

 

 

스크롤을 내릴 때마다 많은 양의 사진을

서버에서 불러오고, 화면에 보여주어야 하는데요.

 

이미지가 로드되는 작업은 무겁기 때문에,

동시에 진행하지 않고 하나씩.. 순서대로

 

 

1번 사진 로드되고 그 다음 2번.. 그 다음 3번 ..

과 같이, 먼저의 작업이 끝날 때까지 기다려야

다음 작업이 진행되면 화면이 버벅일 거예요.

 

 

아무래도 동시에

여러 개의 사진을 한꺼번에 로드하면

끊김없이 자연스럽게 스크롤 화면이 구현되겠죠?

 

 

오늘의 포스팅에서는  iOS Cuncurrency(동시성) 에 대해서 정리해보려 합니다.

 

 

 


✅ 코어와 쓰레드

 

 

동시성에 등장하는 용어들을 공부하기 이전에,

코어랑 쓰레드에 대해 알아야 합니다.

 

코어와 쓰레드는 '4코어 8쓰레드'와 같이

컴퓨터 사양을 설명할 때 언급되는데요.

 

요런 식으루

 

 

 

코어는 작업을 처리할 수 있는 물리적인 공간, 연산 장치

쓰레드는 실질적으로 작업을 수행하는 단위입니다.

 

 

으흠

 

코어와 쓰레드

 

 

약간 이런 거져...?

 

고기의 방. 생선의 방 -> 코어
요리사 -> 쓰레드

 

 

작업을 수행하는 공간, 즉 코어

요리사들이 요리를 하는 주방이라고 생각할 수 있겠구요

 

그 안에서 작업을 수행하는 요리사

쓰레드라고 할 수 있겠습니다.

 

 

이제부터 쓰레드 == 요리사로 비유해서 설명해볼게요.

 

 

 


 직렬과 동시

 

 

여기 한창 팀전 대결을 진행하고 있는 요리사들이 있습니다.

 

 

어느 요리사가 말했어요.

 

나는 소금, 설탕, 후추 가져올게.


 

ㅇㅋ. 조미료 세 개 가져오는 건 쉽잖아요?

 

요리사 혼자 충분히 할 수 있습니다.

 

 

 

그러나...

 

 

나는 리조또 백인분을 볶아볼게.

 

혼자 리조또 백인분 볶기. 파바박

 

 

리조또 백인분 볶기와 같은 힘든 일

한 명의 요리사가 담당한다면 어떨까요..?

 

(물론 맛피아가. 엄청난 능력자인 건. 배제하고..

그냥 일반 요리사라고 생각했을 때..)

 

 

 

맛피아: 왜 나만 볶아?

 

 

요리사(==쓰레드) 혼자 일하고 있으니

아주 과열 상태입니다.

 

 

... 그런데 맛피아 5명이 한꺼번에

20인분씩.. 나눠서 볶는다면 어떨까요

 

파바박 * 5

 

 

5명의 각각 맛피아 셰프님도 덜 힘들고. .

작업도 빨리 끝나겠죠?

 

 

이렇게 전자처럼

요리 20인분씩, 순서대로 5번 반복하는 과정은 직렬(Serial)이라 하고

 

후자처럼

요리 20인분을 동시에 진행하는 과정을 동시, Concurrent이라고 합니다.

 

 

 

동시가 무조건 빠르고 좋은 거 아냐? 싶은데

직렬이 필요한 경우도 있습니다.

 

직렬이 필요한 경우



메쉬드 포테이토 만들기를 진행한다고 할 때,

감자를 삶지 않고 체에 내린다던지 등

순서에 맞지 않게 진행하면 안되겠죠.

 

이처럼 직렬은 이전 작업이 끝나야만 순차적으로 진행되기 때문에,

순서가 중요한 작업에서 활용됩니다.

 

 

 

 

그렇다면 해야하는 작업들이 여러 개 있을 때,

요리사들에게 배정을 해줘야겠죠?

 

iOS 프로그래밍하는 우리의 입장에서,

재료 다듬기 / 썰기 / 볶기  등등의 작업들을 그냥 하나의 공간에 넣어주기만 하면

알아서 요리사에게 배정을 해주는데요.

 

우리가 여러 작업들을 보내는 공간을

대기행렬(Queue)이라고 합니다.

 

iOS에서는 이 대기행렬에 작업들을 보내면,

시스템이 알아서 작업들을 스레드에 나누어 줍니다.

 

대기행렬 == 헤드 셰프

지금부터 대기행렬(Queue)를 헤드셰프라고 해봅시다.

 

 

 


✅ 대기행렬의 종류

 

 

백수저 팀의 헤드 셰프 최현석 님

다른 셰프들에게 작업을 지시하고 있습니다.

 

 

 

저희가 최현석 셰프님에게

 

미역국 재료 준비를 해주세요.


하면 알아서 셰프님이 다른 셰프들에게 작업을 분배해주시겠죠.

 

작업을 분배해주는 Queue

 

 

이러한 헤드셰프, 대기행렬은 iOS에서 크게 두 가지가 있습니다.

 

 

바로 GCD Qperation Queue인데요.

 

- GCD (Grand Central Dispatch) : 간단한 작업을 처리할 때 사용됩니다.
- Operation Queue : 더 복잡한 작업을 처리할 때 사용됩니다. 작업 취소, 순서 지정, 일시 정지 등의 기능을 제공합니다.

 

 

원래 GCD만 처음에 나왔었는데,

더 복잡한 일들(취소, 순서 지정, 일시중지)와 같은 일들이 더 필요하다고 해서

한계를 보완하기 위해 2016년에 애플이 추가적으로 발표한 것이

Operation Queue라고 합니다.

 

(이후의 글에서 더 자세히 서술합니다.)

 

 

 

GCD를 사용하기 위한 형식은 아래와 같은데요.

 

DispatchQueue.global().async { /* 작업 */ }

 

 

DispatchQueue: 말 그대로 Queue에 보내겠다.

global(): 어떤 Queue? 동시 처리를 위한 Queue로

async: 비동기적으로.

 

요렇게 DispatchQueue.global().async { 작업 } 한 개를 생성하면

이 친구가 작업 한 개가 되겠습니다.

 

두 개 만들면 두 개의 작업이 만들어지는 거구요 ..

 

 

으응? 근데

async라는 단어가 등장하네요.

 

aysnc는 Asynchronous의 줄임말로,

한국어로는 비동기라는 뜻인데요.

 

비동기에 대해 자세히 알아봅시다.

 

 

 


✅ 동기와 비동기

 

비동기를 설명하기 전에,

그 반대인 동기에 대해 먼저 얘기해보겠습니다.

 

동기는 한 번에 한 개의 작업만 진행하고

그 작업이 끝나야만 다음 작업을 진행하는 방식인데요.

 

예를 들면...

최현석 셰프님이 요리사들에게 일을 시킬 때

한 명 끝날 때까지 감시하고.. 그 분 완료하면

그 다음 한 명 끝날 때까지 감시하고.. 다음 분 완료하면

또 그다음..

 

동기 작업 모습

 

 

그림으로 나타내면 위와 같은데요.

 

최현석 셰프님이.. 한번에 한 명씩 일을 잘 처리하고 있나

확인하고 있어요

 

 

크크

 

 

그만큼 시간도 오래 걸리겠죠?

 

 

 

반대로 비동기 작업은 최현석 셰프님이 여러 스레드에게 일감을 맡기고,

그 일이 완료될 때까지 기다리지 않습니다.

 

 

비동기 작업 모습

 

 

우리가 프로그래밍 할 때 비동기 작업은

대부분 서버와의 통신에서 사용됩니다.

 

서버에 요청을 보내고,

답변이 오기까지 얼마나 걸릴지 모르는데

동기 작업에서의 최현석 셰프님처럼

답이 오는지 안 오는지 메인 쓰레드가 꼭 확인해야 다음 작업을 할 수 있다면..

 

말이 안되겠쬬

 

그래서 서버 통신 시에,

백그라운드에서 데이터를 비동기적으로 가져오며

메인 스레드는 사용자 인터페이스를 원활하게 유지시켜줍니다.

 

 

 


✅  비동기랑 동시, 헷갈리지 말기!

 

지금까지 앱이 여러 작업을 효율적으로 동시에 처리할 수 있도록 도와주는

iOS Concurrency를 본격적으로 익혀보기 전에,

주요 개념들을 알아보았는데요.

 

비동기(Async)동시(Concurrency)에 대해 헷갈리는 경우가 많은데,

다시 한 번 정리해보겠습니다.

 

비동기는 분산처리(작업을 여러 쓰레드에 나누어주고)하고 그 작업이 끝나길 기다리지 않고 다음 작업을 생성하는 것을 의미하며,
동시는 작업들이 여러 스레드에 분산되어 동시에 처리되는 것을 의미합니다.

 

 

결론적으로,

비동기는 메인 스레드를 방해하지 않고 작업을 계속 진행할 수 있게 돕고,

동시는 시스템의 여러 스레드를 활용해 작업을 동시로 진행해준다

 

정도로 이해하면 되겠습니다.

 

 

 

읽어주셔서 감사합니다.

잘못된 부분이 있으면 지적해주세요!