iOS

[iOS] 멀티 스레드(Multi Thread) 구현 시 고려해야될 것들

사용자 gwangyonglee 2020. 1. 5. 02:07

안녕하세요. iOS앱을 개발하면서 멀티 스레드로 앱을 구현하다보면 예상하지도 못한 곳에서 죽는 경우를 경험해보셨을 것입니다. 

그래서 이번 글에서는 멀티 스레드를 구현하면서 고려해야될 것들을 정리해보려고 합니다. 

멀티스레딩이란?

여러 개의 스레드가 동시에 진행되는 것을 의미합니다. 하나의 프로세스 내에서 여러 개의 스레드가 존재하고, 스레드들이 프로세스의 자원을 공유하되 실행은 독립적으로 이루어지는 구조입니다. 

멀티스레딩의 장점 

1. 메모리 공간과 시스템 자원 소모가 줄어든다.

 

2. 프로세스간 통신 방법에 비해 스레드간의 통신 방법이 간단하다. 

-> 별도의 자원을 이용하는 것이 아니라 전역 변수의 공간 또는 동적으로 할당된 공간인 Heap 영역을 이용하여 데이터를 주고 받기 때문)

멀티스레딩의 단점

1. 서로 다른 스레드가 데이터와 Heap영역을 공유하고 있기 때문에 어떤 스레드가 다른 스레드에서 사용 중인 변수나 자료구조에 접근하여 엉뚱한 값을 읽어올 수 있다. 

-> 멀티 프로세스는 프로세스간 공유하는 자원이 없기 때문에 동일한 자원에서 동시에 접근하는 경우가 없다)

 

2. 병목현상이 발생하여 성능이 저하될 가능성이 있다.

->과도한 락(lock)으로 인한 병목현상을 줄여여합니다.

멀티스레딩 프로그래밍시 고려해야될 것

가장 기본적으로는 UI업데이트에 관한 작업들은 메인 스레드(main thread)에서 구현되어야 합니다. 

그리고 가장 신경써야될 작업은 스레드에 안전하지 않은(Thread-unsafe) 변수는 서로 다른 스레드에서 동시에 접근하면 위험하기 때문에 해당 작업에 신경을 많이 써야 합니다.

1) Mutable, Immutable 

Immutable한 인스턴스는 스레드에 안전(Thread-safe)합니다. 

즉, 여러 스레드에서 한번에 접근해도 문제가 되지 않습니다. 

 

Mutable한 인스턴스는 스레드에 안전(Thread-safe)하지 않지만 읽기 전용으로만 사용한다면 문제가 되진 않습니다.

하지만 Mutable한 인스턴스를 하나 이상의 스레드에서 변경이 이루어진다면 문제가 발생합니다. 

 

2) 프로퍼티 속성

프로퍼티 속성에는 atomic, nonatomic이 있습니다. 

 

어떤 프로퍼티를 두 개의 스레드가 참조하고 있는 상황에서 해당 프로퍼티 접근자 메서드가 atomic하지 않는다면 값에 대한 싱크가 맞지 않아 문제가 발생할 수 있습니다. 이런 경우에 atomic으로 설정되어야 합니다. 

 

하지만, Mutable한 인스턴스가 변경 중에 동시 접근할 경우가 없다면 nonatomic으로 사용해도 무방합니다. 

 

3) Synchronized

메소드를 실행할 때 동시에 접근할 수 없도록 막고 싶을 때 해당 부분을 Lock을 걸 수 있습니다. 

Lock을 걸어줌으로써 한 스레드에서 해당 부분이 끝낼 때 까지 다른 스레드에서 접근할 수 없게됩니다.

 

4) GCD

Swift에서 스레드 관련 작업은 Grand Central Dispatch API를 통해 처리합니다.

GCD는 클로저 블록 안에 있는 특정 작업을 큐에 올리고, 해당 큐를 특정 스레드에 실행하는 방식입니다. 

 

애플이 스레드 프로그래밍을 효율적으로 할 수 있게 만들어준 만큼 적절하게 사용하여 Thread-safe하게 구현하는 것이 중요합니다.

 

5) Class, Struct

클래스는 레퍼런스 타입, 구조체는 값 타입입니다. 즉, 구조체가 파라미터로 전달될 때 스레드에 안전(Thread-safe)합니다.

 

마무리

멀티 스레드를 사용하여 개발을 할 때에는 스레드에 안전하지 않은(Thread-unsafe) 변수를 사용하고 있다면 변경 중에 동시에 접근하는 경우가 있는지 잘 체크해야합니다.