Dog foot print

[IOS] 쓰레드와 동시작업 본문

IOS/Swift

[IOS] 쓰레드와 동시작업

개 발자국 2021. 9. 22. 17:20

쓰레드란 무엇인가 ?

쓰레드를 쉽게 이해하기위해서는 내 Application에서 동작하는 일꾼 이라고 생각 할 수 있다.

우리의 어플리케이션이 동작 할 때도 이런 쓰레드에게 일을 맡겨야 하는데, 우리가 만약 별도의 쓰레드에게 일을 맡기지 않는다면 메인 쓰레드 에서 일을 모두 하게 된다.

쓰레드를 생성하고 삭제하는 일을 꽤나 고난이도의 일이다. 그렇기에 IOS에서는 친절하게도 쓰레드를 생성하거나 삭제하는 일을 대신 해주고 우리는 별도의 쓰레드에게 일을 시키기만 하면 된다.

별도의 쓰레드에게 일을 시키는 이유

이런 의문이 들 수 있다. 현재까지 쓰레드를 나누지 않고, 잘만 사용 되던데요. 굳이 다른 쓰레드에게 일을 시키는 상황이 있을까요 ?

합리적인 질문이다. 우리의 IOS CPU의 성능은 정말이지 엄청나다. 그렇기 때문에 간단한 일들은 메인 쓰레드가 이를 모두 처리해도 우리의 Application이 버벅이는 현상은 쉽게 볼 수 없다.

우리의 메인 쓰레드는 일을 동기적으로 처리한다. 아래의 코드를 보도록 하자.

var a = 0;

func add1(){
    a = 1
}

func add2(){
    a = 2
}

add1() //1
add2() //2

print(a)

위의 코드는 순차적으로 실행 되며, 별도의 쓰레드를 두지 않은 코드이다. 아래의 print 결과를 예상 해본다면 답은 2이다. 이유는 순차적으로 코드가 실행 되었고 add2 함수가 마지막에 실행 되었기 때문이다. 여기서 중요한 것은 순차적으로 실행 되었다는 점이다. 즉메인 쓰레드는 오래걸리는 일이던 뭐던 자신에게 주어진 일을 순차적으로 진행 한다는 점이다.

만약 메인쓰레드가 네트워크를 통해서 이미지를 다운로드 하는데 1초, 블러처리를 하는데 2초, 화면에 렌더링 하는데 0.5초 걸린다고 하면 어떤 이미지를 보기위해서 사용자는 3.5초 동안 아무것도 못하고 기다려야 한다. 이유는 메인 쓰레드가 화면을 업데이트하는 역할을 하는데, 오래걸리는 작업을 미리 끝내야 하기 떄문에 유저에게는 화면이 멈춘 것 처럼 보이는 것이다.

이를 위해서 별도의 일꾼에게 오래걸리는 작업을 할당시키고 메인 쓰레드는 화면을 업데이트 하며 사용자와 상호작용을 한다면 사용자의 화면이 멈추는 일을 없을 것이다.

QUEUE의 개념과 QUEUE가 동시성 프로그래밍에서 어떤 일을 하는가 ?

QUEUE에 대해서는 자세히 다룬 포스팅이 있기 때문에 개념에 대해서 간략히 설명하면
먼저 들어 온 일을 먼저 처리하는 선입선출 (First In First Out) 의 성질을 띈 자료구조이다.

위에도 언급 하였듯이 쓰레드를 직접 관리하는 일은 매우 고난이도의 작업이며 쓰레드의 관리가 제대로 되지 않은 경우 앱이 종료되는 경우가 존재 할 수 있다. 이렇게 때문에 우리는 인력 사무소 처럼 일감을 일꾼들에게 배분하는 역할인 QUEUE 에 전달 하여, QUEUE가 쓰레드에게 자동으로 일을 배분하게 끔 해야 한다.

메인 쓰레드에서 어떤 작업을 다른 쓰레드에게 요청하는 경우 QUEUE에 이 작업을 적절한 쓰레드에게 배치한다. 이후 전달한 작업은 QUEUE에서 제거된다.

IOS에서 작업을 분배하는 DispatchQueue 비동기 예시

 

print("메인쓰레드에서 작동 중")
for index in 0...2{
    print(index + 1)
    DispatchQueue.global().async {
        print("\(index) 작업이 다른 쓰레드에서 발생 합니다.")
    }
}

코드를 구분해서 보도록 하겠다.

  • DispatchQueue
    • 쓰레드에게 작업을 분배하는 QUEUE
  • .global()
    • main 쓰레드가 아닌 다른 쓰레드에게
  • async { 작업 }
    • 작업이 비동기적으로 이루어지게 해주세요.

위의 결과가 순차적으로 1, 2. 3 이 프린트 될 것이라고 예상 되지만 메인쓰레드에서 작동한 print 구문 이외에는 예측 할 수 없다. (위의 작업은 너무 간단해서 1 2 3으로 프린트 될 가능성이 높다. )

그 이유는 다음과 같다.

 

빠르게 메인쓰레드에서는 print() 를 싫행하고 디스패치 큐로 작업을 보낸다. 이 과정에서 print(1)이후에 작업을 전달하고 다시 print(2)를 실행하기 전에 전달된 작업이 실행 될 수도 있고 실행이 안 될 수도 있다. 즉 다른 쓰레드로 전달한 작업은 그 순서를 보장하지 않는다. 

반응형

'IOS > Swift' 카테고리의 다른 글

[IOS] Serial & Concurrent Queue  (0) 2021.09.23
[IOS] Async & Sync  (0) 2021.09.23
[Swift] 동기적 작업과 비동기적 작업  (0) 2021.09.20
[SWIFT] protocol  (0) 2021.07.21
[SWIFT] enumeration  (0) 2021.07.21
Comments