[iOS] Concurrency Programming 용어

RudinP·2024년 7월 6일
0

Study

목록 보기
248/258

Concurrency Programming

모바일에서는 적절한 시점에 알맞은 실행을 통한 터치 반응성이 중요하다. 특히 스레드를 구현하는 부분이 중요하다.
애플 플랫폼에서도 스레드를 제공하지만 거의 사용하지 않고 GCDSwift Concurrency를 사용하며, 최근에는 후자를 더 많이 사용하는 추세다. Operation Queue도 존재하지만 자주 사용하지는 않는다.

Process

앱 실행 시 iOS가 앱을 실행하고 인스턴스를 만드는데, 이 때 만들어지는 인스턴스를 Process라고 한다. 프로세스별로 OS로부터 메모리를 할당받는다. 할당받은 메모리는 독립적이다.
예시로, 카메라앱과 사진앱은 서로의 메모리와 리소스에 접근할 수 없다. 직접 접근은 불가능하지만, 간접 접근(IPC)로 내부적인 통신을 구현하여 접근 가능하다.

Single Process & Multi Process

OS가 하나의 앱을 실행할 때 반드시 하나의 프로세스를 생성하지는 않는다. 하나면 Single, 두 개 이상은 Multi.

Single: 프로세스 하나. 작업을 순차적으로 실행. 전반적 성능 떨어짐. 메모리는 하나만.

  • 모든 데이터가 하나의 메모리에 존재하므로 접근 방식을 고려하지 않아도 됨.
  • 프로세스에서 문제가 발생하면 프로그램이 강제로 종료된다.

Multi: 두 개 이상의 프로세스가 작업을 개별적으로 실행. 작업의 성격에 따라 동시 실행도 가능. 싱글에 비해 전반적 성능 높음. 메모리는 프로세스의 수만큼.

  • 저장할 수 있는 메모리 구역이 여러개이므로, 같은 앱이더라도 하나의 프로세스에서 다른 프로세스로 직접 접근하는 것은 불가능하다.
  • IPC를 통해 프로세스 사이의 통신을 구현할 필요가 있다.
  • 동기화도 구현해야 한다.
  • 개별 프로세스가 독립적이므로 하나의 프로세스에서 문제가 발생하더라도 다른 프로세스에는 문제가 없고, 프로그램 자체는 실행되므로 안정성이 높다.

Context Switching

CPU는 본질적으로 한 번에 하나의 작업밖에 하지 못한다.
하나의 프로세스에서 다른 프로세스로 넘어가 작업을 처리하는 것을 Context Switching이라고 한다.
넘어가기 전에 어떤 작업을, 어떤 상태로, 메모리에 무엇이 저장되어 있었는지, 어떤 리소스를 사용하고 있었는지 따로 저장해두어야 한다. 이는 PCB에 저장된다.
Context Switching이 자주 발생하면 성능 저하가 발생한다.

Thread

하나의 프로세스에는 여러가지의 스레드가 존재할 수 있다.
스택을 제외한 나머지 공간은 모든 스레드가 공유한다. 스택은 스레드마다 개별적으로 만들어진다. 따라서 필요한 데이터를 다른 스레드와 공유할 수 있게 된다. 그렇기때문에 멀티 프로세스의 컨텍스트 스위칭보다는 멀티 스레드의 컨텍스트 스위칭의 오버헤드가 더 작다.

Multi Process vs Multi Thread

컨텍스트 스위칭: Process 보다 Thread가 빠르고 오버헤드 작음
데이터/리소스 공유: Process는 IPC 구현, Thread는 공유 메모리/리소스에 바로 접근
안전성: ProcessThread보다 높다.

  • 멀티 프로세스는 하나의 프로세스에 문제가 발생해도 다른 프로세스에 영향을 크게 주지 않지만 스레드는 공유자원이 있기 때문에 그렇지 않다.

iOS 앱의 Concurrency 모델

iOS에서는 멀티프로세스와 멀티 스레드를 모두 지원하지만 하나의 앱에서는 싱글 프로세스, 멀티 스레드를 기본 모델로 사용하고 있다.

Main Thread와 Background Thread

Main Thread: UI Updates, Touch Events //모든 플랫폼에서 동일
Background Thread: Long-running Tasks //파일 다운 등

가장 기초적, 중요한 규칙

  • 메인 스레드에서는 화면 업데이트, 터치 이벤트 처리, 아주 짧은 시간에 완료 가능한 코드만
  • 그 외에는 무조건 백그라운드

메인 스레드는 OS가 자동으로 만들어주는 것 하나뿐이다.
메인 스레드를 제외한 WorkerThread(Background Thread)는 필요할때마다 언제든지 만들어도 된다.
다만 스레드 개수가 늘어날수록 컨텍스트 스위칭으로 인한 오버헤드가 증가하므로 필요한 수만 사용하는 것이 바람직하다.

Inter-Process Communication(IPC)

프로세스 사이의 통신.
프로세스마다 메모리 구역과 리소스를 개별적으로 가지고 있고 독립적이므로 다른 프로세스에서 바로 접근하지 못한다.
IPC에는 여러가지 형태가 있다.

  • 파일을 만들어서 데이터를 공유
  • 하나의 프로세스에서 이벤트가 발생하면 OS가 다른 프로세스에 시그널을 보내기
  • 파이프나 소켓을 통해 프로세스를 연결하기

iOS에서는?

iOS에 특화된 샌드박스 보안모델을 사용하기 때문에 일반적인 IPC 대신 다른 방법을 제공한다.
IPC의 예: 카카오톡 로그인 시 카카오톡이 실행되었다가 다시 본래 앱으로 돌아가는 기능(URL Scheme)

  • URL Schemes
  • Universal Clipboard
  • App Extensions
  • Shared Keychain

Race Condition과 Synchronization

Race Condition: 두 개 이상의 프로세스에서 동시에 동일한 데이터에 접근하는 상황
이를 해결하기 위해 동기화(synchronization)을 구현해야 함.

  • Mutex, Lock, Semaphore, Monitor 등을 사용

Sync와 Async

에이싱크라고 읽는 것에 주의하자
  • 동기(sync): 하나의 작업이 끝나고 다음 작업 실행.
    • 실행 순서와 흐름을 예측하기 쉽지만 오래걸린다.
  • 비동기(async): 하나의 작업이 끝나지 전에 다른 작업 실행 가능
    • 전체 작업은 빠르게 끝나지만 실행 순서 예측이 어려워 구현이 까다롭다.
    • Callback, Promise, Future 등을 사용

Serial, Parallel, Concurrent

  • Serial(직렬, 순차): 작업을 하나씩 순차적으로 실행. 각 작업이 독립적.
  • Parallel(병렬): 여러 작업을 동시에 실행. 동기화 문제 발생
  • Concurrent(동시 처리): 병렬과 다르다. 병렬은 빠르게 완료에 포커스를 두고, 멀티코어 멀티프로세스 환경에서만 구현 가능하다. 그러나 동시 처리는 작업이 동시에 실행될 수 있지만 동시에 시작되지는 않는다. 그냥 같은 시간에 여러개의 작업이 실행될 수 있을 뿐이다. 싱글, 멀티에 관계없이 구현 가능.(그냥 동시에 실행하는 것처럼 보이는거고 실제로는 Context Switching)
profile
iOS 개발자가 되기 위한 스터디룸...

0개의 댓글