개발을 시작하는 이야기

Multi Thread를 구현해보자 (2) 본문

개발 이야기/우리동네 문화유산 :: JHeritage

Multi Thread를 구현해보자 (2)

Teiresias 2022. 4. 27. 22:25

이전에 그럼 우린 스레드와 프로세스에 대해서 알아봤다.

프로세스는 실행될때 운영체제로 부터 각각 독립된 메모리 영역을 할당받지만 스레드는 프로세스 내에서 스텍 영역만 별도로 할당받고 부모 프로세스의 Code, Data, Stack, Heap 영역은 공유하게 된다. 따라서 프로새스 내에서 자식 스레드들은 서로 주소 공간이나 자원을 공유하면서 실행될 수 있다. (스텍은 서로간의 데이터 공유가 수월하지만 프로세스간의 데이터 공유는 그렇지 않다고 한다. 하지만 불가능 한것은 아니라고 함)

그럼 이젠 멀티 스레드에 대해 알아보자

멀티스레드는 하나의 어플리케이션을 여러개의 스레드로 구성하여 하나의 스레드가 하나의 작업을 처리하도록 하는 것이다. 만일 단일 스레드로 네트워크나 데이터베이스 통신과 같은 긴 작업을 수행하는 경우 다른 작업을 처리할 수 없기 때문에 여러개의 스레드를 사용한다.

 그러니까 우리동네 문화유산을 실행할때 만육천개의 XML 데이터를 파싱하는 도중에 앱을 실행할 수 있도록 하는 것이다. 

 

멀티 스레드의 장점

  • 메모리 공간과 시스템 자원 소모가 줄어든다.
  • 프로세스간 통신 방법에 비해 스레드간의 통신 방법이 간단하다.
    • 별도의 자원을 이용하는것이 아닌 전역 변수의 공간 또는 동적으로 할당된 공간인 Heap 영역을 이용해서 데이터를 주고받는다.
  • 응답성이 좋다.
    • 자식 스레드중 하나가 오류 또는 긴 작업으로 중단되어도 프로그램이 계속적으로 동작한다.

멀티 스레드의 단점

  • 구현, 테스트, 디버깅이 어렵다.
  • 스레드간 별도의 동기화 작업이 필요하며, 교착상태가 발생하지 않도록 주의해야 한다. 
  • 자식 스레드중 하나에 문제가 생기면 전체 프로세스에 영향을 미칠 수 있다.
  • 서로 다른 스레드가 데이터와 Heap 영역을 공유하기 때문에 다른 스레드에서 사용중인 변수나 자료구조에 접근해서 엉뚱한 값을 가져올 수 있다.

멀티 스레딩의 장점도 많지만 그만큼 단점도 많다. 하지만 단점은 구현하는 방식에 따라 단점을 얼마든지 보완할 수 있는 영역이라고 볼 수 있다.

멀티 스레딩 구현시 고려해야 할 것

가장 기본적으로 UI 업데이트와 관련된 작업들은 메인 스레드(Main Thread)에서 구현되어야 한다. 그리고 가장 신경써야 할 부분은 스레드에 안전하지 않은 변수는 서로 다른 스레드에서 동시에 접근하면 위험하기 때문에 해당 작업에 신경을 많이 써야 한다.

1. Mutable, Immutable

Immutable한 인스턴스는 스레드에 안전하다. 즉, 여러 스레드에서 한번에 접근해도 문제가 되지 않는다.

Mutable한 인스턴스는 스레드에 안전하지 않지만, 읽기 전용으로만 사용한다면 문제가 되지 않는다. 하지만 Mutable한 인스턴스를 하나 이상의 스레드에서 변경이 이루어진다면 문제가 발생한다.

2. 프로퍼티 속성

프로퍼티 속성에는 atomic과 nonatomic이 있다. 어떤 프로퍼티를 두개의 스레드가 참조하고 있는 상황에서 해당 프로퍼티 접근자 메서드가 atomic하지 않는다면 갑에 대한 싱크가 맞지 않아 문제가 발생할 수 있다. 이런 경우에는 atomic으로 설정되어야 한다. 하지만, Mutable한 인스턴스가 변경 중에 동시 접근할 경우가 없다면 nonatomic으로 사용해도 무방하다.

3. Synchronized

메소드를 실행할 때 동시에 접근할 수 없도록 막고 싶을 때 해당 부분을 Lock을 걸어줄 수 있다. Lock을 걸어줌으로써 한 스레드에서 해당 부분이 끝날 때 까지 다른 스레드에서 접근할 수 없게 된다.

4. GCD

swift에서 스레드 관련 작업은 Grand Central Dispatch API를 통해 처리한다. GCD는 클로저 블록 안에 있는 특정 작업을 큐에 올리고, 해당 큐를 특정 스레드에 실행하는 방식이다.  애플이 스레드 프로그래밍을 효율적으로 할 수 있게 만들어준 만큼 적절하게 사용하여 스레드를 안전하게 구현하는것이 중요하다.

5. Class, Struct

클래스는 레퍼런스 타입, 구조체는 값 타입이다. 즉, 구조체가 파라미터로 전달될 때 스레드가 안전하다. 애플에서는 클래스보다 구조체 사용을 권하는 이유는 여러가지가 있지만 그중 하나이지 않을까 싶다.


글을 작성하며 하나씩 알아가며 정리하고 있는데, 문득 Process의 구성인 Code, Data, Stack, Heap 도 궁굼해지고, Process의 Stack과 Thread 의 Stack도 궁굼해져서 내일은 이것을 좀 더 알아볼까 한다.

그리고 티스토리의 줄바꿈은....작성할때는 괜찮아도 완성해서 보면 이상해지는게 적응이 안되네....