Skip to content

[LEVEL 1] 26.2 - GCD #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

[LEVEL 1] 26.2 - GCD #43

wants to merge 1 commit into from

Conversation

mint3382
Copy link
Member

26.2 - GCD

글로벌 큐(Global Queue)와 메인 큐(Main Queue)는 어떻게 다르나요?

  • 두 개의 큐 모두 이미 만들어져있는 큐.

  • DispatchQueue.main

    • Serial Queue
    • main 큐에 작업을 추가하면, main 스레드에서 처리한다.
    • 앱이 실행되는 동안에는 늘 메모리에 올라와 있다.
    • 때문에 앱의 생명주기와 같은 생명주기를 가지며 main이 멈추면, 앱이 멈춘다.
    • 전역적으로 사용이 가능하다.
    • Main Runloop가 자동으로 설정되고 실행된다.
    • UI 작업은 main에서만 가능하다.
  • DispatchQueue.global()

    • Concurrent Queue
    • global()이 호출되면 스레드가 작업을 처리하기 위해 메모리에 올라왔다가, 작업이 끝나면 제거된다.

main은 property, global()은 method인 이유?

  • main은 언제나 메모리에 올라와 있는 Default지만, global()은 매번 새로운 스레드를 만들어서 사용하지 때문에 다르지 않을까 싶다.

main.sync?

  • main에서 main.sync를 호출하면, deadlock에 빠지게 된다.
  • sync는 작업이 끝나기를 기다리기에 main에서 main.sync를 호출하면 main 스레드는 sync의 작업이 끝나기를 기다린다.
  • 그런데 이때 작업을 해야하는 sync의 코드 블록도 main에서 실행되고 있던 코드이기에 똑같이 멈춰버린다.
  • main은 sync가 끝나길, sync는 main이 동작하기를 기다리며 영원히 멈춰있게 된다.

UI 작업을 main에서 해야하는 이유?

  • UIKit은 Thread Unsafe하기 때문에 여러 스레드에서 접근이 가능하다.
  • 이는 Race Condition을 발생시킬 수 있고 이렇게 되면 의도대로 화면이 그려지지 않을 수 있고 때문에 Serial Queue가 필요하다.
  • 다른 Serial Queue에 넣을 수도 있겠지만, UI를 그리기 위해서는 일정한 주기(View Drawing Cycle)에 맞추어 동작하는 RunLoop가 필요하다.
  • 해당 주기에 맞추어 입력을 받아 UI를 그리기 때문이다.
  • 모든 스레드가 각자의 RunLoop를 따라 UI를 그리게 된다면 UI가 그려지는 시점이 모두 달라진다.
  • 이는 또다시 Race Condition이 일어날 수 있는 조건이 되기에, 기준을 Main RunLoop로 맞춰서 해결하는 것이다.
  • 또한 자동으로 실행되는 RunLoop가 Main RunLoop밖에 없기 때문이기도 하다.

RunLoop?

  • 작업을 예약하고 들어오는 이벤트 수신을 조정하는 데 사용하는 이벤트 처리 루프이다.
  • 작업이 있을 때는 스레드를 바쁘게 유지하고, 작업이 없을 때는 스레드를 휴면 상태로 만드는 것을 목적으로 둔다.

image

  • 이는 RunLoop의 동작 방식에서 알 수 있는데, 그림의 Input Source처럼 이벤트가 들어오더라도 RunLoop를 실행시키지 않는다면, RunLoop는 대기 상태에서 기다리며 이벤트를 처리하지 않는다.

스크린샷 2025-01-23 오후 3 00 29

  • 위와 같은 4개의 함수를 사용해 RunLoop를 작동시키면, 그제서야 이벤트를 받고, 이에 대한 작업 처리를 한다.
  • 때문에 main이 아닌 스레드에서 RunLoop가 필요한 작업을 하기 위해서는 개발자가 별도로 RunLoop를 반복 실행하는 로직이 필요하다.
  • main의 Main RunLoop는 앱이 실행될 때 프레임워크 차원에서 자동으로 RunLoop를 설정하고 실행한다.

@mint3382 mint3382 self-assigned this Jan 23, 2025
@mint3382 mint3382 linked an issue Jan 23, 2025 that may be closed by this pull request
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[LEVEL 1] 26. GCD
1 participant