Skip to content

Latest commit

 

History

History
178 lines (110 loc) · 9.49 KB

8차 스터디.md

File metadata and controls

178 lines (110 loc) · 9.49 KB

8차 스터디


비동기처리(개념만 간단히 8차때도 이어서..)

  • sync VS async
  • sync: 해당작업이 끝나야 다음 작업으로 넘어감
  • async: 큐에 작업을 올려놓지만 작업의 완료 및 순서는 보장하지 않는다.
DispatchQueue.global().async { print("1") }
      print("2")
      DispatchQueue.global().async { print("3") }
      print("4")
      DispatchQueue.global().async { print("5") }
      print("6")

실행시 2 1 4 3 6 5


얼핏보면 async의 1,3,5가 순서대로 작업되는 것 같지만 계속 실행 시켜보면 아래의 결과값 처럼 5가 출력되고 3이 출력되게 된다. 즉 이 코드에선 2,4,6만이 출력순서가 보장된다.


1 2 4 6 5 3


Dispatch

시스템에서 관리하는 큐를 디스패치하는 작업을 제출하여 멀티 코어 하드웨어에서 코드를 동시에 실행합니다.

개요 GCD (Grand Central Dispatch)라고도하는 Dispatch에는 macOS, iOS, watchOS 및 tvOS의 멀티 코어 하드웨어에서 동시 코드 실행 지원에 대한 체계적이고 포괄적 인 개선 기능을 제공하는 언어 기능, 런타임 라이브러리 및 시스템 향상 기능이 포함되어 있습니다. BSD 하위 시스템, Core Foundation 및 Cocoa API는 모두 이러한 향상된 기능을 사용하여 시스템과 응용 프로그램을보다 빠르고 효율적으로 실행하고 응답 성을 향상시킬 수 있도록 확장되었습니다.

단일 애플리케이션이 여러 코어를 효과적으로 사용하는 것이 얼마나 어려운지 고려하십시오. 컴퓨팅 코어 수가 다른 여러 컴퓨터 나 여러 코어가 경쟁하는 환경에서 수행하는 것은 아닙니다. 시스템 수준에서 작동하는 GCD는 실행중인 모든 응용 프로그램의 요구를보다 잘 수용하여 사용 가능한 시스템 리소스와 균형 잡힌 방식으로 일치시킬 수 있습니다.

DispatchQueue

앱의 메인 스레드 또는 백그라운드 스레드에서 작업 실행을 직렬 또는 동시에 관리하는 객체입니다.

DispatchQueue class : DispatchObject

개요 디스패치 큐는 응용 프로그램이 블록 개체 형태로 작업을 제출할 수있는 FIFO 큐입니다. 디스패치 큐는 작업을 직렬 또는 동시에 실행합니다. 디스패치 큐에 제출 된 작업은 시스템이 관리하는 스레드 풀에서 실행됩니다. 앱의 메인 스레드를 나타내는 디스패치 큐를 제외하고 시스템은 작업을 실행하는 데 사용하는 스레드를 보장하지 않습니다. 작업 항목을 동기식 또는 비동기식으로 스케줄합니다.(synchronously or asynchronously) 작업 항목을 동기식으로 스케줄하면 코드는 해당 항목의 실행이 완료 될 때까지 대기합니다. 작업 항목을 비동기식으로 예약하면 작업 항목이 다른 곳에서 실행되는 동안 코드가 계속 실행됩니다.


중요: 기본 큐에서 작업 항목을 동기식으로 실행하려고하면 교착 상태(deadlock)가 발생합니다.


과도한 스레드 생성 방지

동시 실행 작업을 디자인 할 때는 현재 실행 스레드를 차단하는 메서드를 호출하지 마십시오. 동시 디스패치 큐에 의해 스케줄 된 태스크가 스레드를 차단하면 시스템은 추가 큐를 작성하여 큐에있는 다른 동시 태스크를 실행합니다. 너무 많은 작업이 차단되면 시스템에 앱의 스레드가 부족할 수 있습니다. 앱이 너무 많은 스레드를 소비하는 또 다른 방법은 개인 동시 디스패치 큐를 너무 많이 만드는 것입니다. 각 디스패치 큐는 스레드 자원을 소비하므로 추가 동시 디스패치 큐를 작성하면 스레드 소비 문제가 악화됩니다. 개인 동시 큐를 작성하는 대신 글로벌 동시 디스패치 큐 중 하나에 태스크를 제출하십시오. 직렬 작업의 경우 직렬 대기열의 대상을 전역 동시 대기열 중 하나로 설정하십시오. 이렇게하면 스레드를 생성하는 별도의 큐 수를 최소화하면서 큐의 직렬화 된 동작을 유지할 수 있습니다.


Serial : Serial queues(private dispatch queues라고 알려진)은 큐에 추가된 순서대로 한번에 하나의 task를 실행합니다. 현재 실행중인 task는 dispatch queues에서 관리하는 고유한 쓰레드(task마다 다를 수 있음)에서 실행됩니다. Serial queues는 종종 특정 자원에 대한 액세스를 동기화 하는데 사용됩니다. 필요한 만큼 Serial queues를 작성 할 수 있으며, 각 큐는 다른 모든 큐와 관련하여 동시에 작동합니다. 다시말해, Serial queues을 4개 작성하면 각 큐는 한번에 하나의 task만 실행하지만, 최대 4개의 task가 각 큐에서 동시에 실행될 수 있습니다.

Concurrent : Concurrent queues(일종의 global dispatch queue라고도 알려진)은 동시에 하나 이상의 task를 실행하지만 task는 큐에 추가된 순서대로 게속 시작됩니다. 현재 실행중인 task는 dispatch queue에서 관리하는 고유한 쓰레드에서 실행됩니다. 특정 시점에서 실행되는 정확한 task의 수는 가변적이며 시스템 조건에 따라 다릅니다. iOS 5이상에서는 큐의 타입으로 DISPATCH_QUEUE_CONCURRENT를 지정하여 사용자가 동시에 dispatch queue을 생성 할 수 있습니다. 또한 앱에 사용할 사전에 정의된 global concurrent queues가 4개 있습니다.

Main dispatch queue : main dispatch queue는 앱의 main 쓰레드에서 task를 실행하는, 전역적으로 사용 가능한 serial queue입니다. 이 큐는 앱의 실행루프와 함께 작동하여 큐에 있는 task의 실행을 실행루프에 연결된 다른 이벤트 소스의 실행과 얽힙니다. 앱의 main쓰레드에서 실행되므로, main queue는 종종 앱의 주요 동기화 지점으로 사용됩니다. main dispatch queue를 만들 필요는 없지만, 앱이 적절하게 배수(drains)되도록 해야합니다.

출처: https://zeddios.tistory.com/513 [ZeddiOS]


dispatch queues에 대해 기억해야 할 다른 주요 사항은 다음과 같습니다.

  • Dispatch queues는 다른

    Dispatch queues와 관련하여 동시에 task를 실행합니다. task의 직렬화는 single dispatch queue의 task로 제한됩니다.

  • 시스템은 한번에 실행되는 총 task수를 결정합니다. 따라서, 100개의 다른 큐에서 100개의 task를 가진 앱은(100개 이상의 유효코어가 없는 한) 모든 task를 동시에 실행 할 수 없습니다.

  • 시작될 새 task를 선택 할 때, 큐 priority level이 고려됩니다. Serial queue priority를 결정하는 방법은 Providing a Clean Up Function For a Queue를 참고하세요.

  • 큐의 task는 큐에 추가 될 때, 실행할 준비가 되어있어야 합니다. 이전에 Cocoa Operation queue를 사용했다면, 이것이 model operation에 사용되는 것과 다르다는 점에 유의하세요

  • Private dispatch queues는 reference-counted객체입니다. 자신의 코드에 큐를 유지하는 것 외에도, dispatch sources를 큐에 첨부될 수 있으며 retain count를 증가시킬 수 있다는 점에 유의해야합니다. 따라서 모든 dispatch sources가 취소(canceled)되었는지 확인하고, 모든 retain call이 적절한 release call과 균형을 이루도록 해야합니다.

출처: https://zeddios.tistory.com/513 [ZeddiOS]


적절하게 QoS를 지정해주면 앱의 에너지 효율이 좋아진다는 것!

DispatchQueue.global(qos: DispatchQoS.QoSClass).async { 

}

<QosClass 종류>

QosClass종류

case userInteractive
The quality-of-service class for user-interactive tasks, such as animations, event handling, or updating your app's user interface.

case userInitiated
The quality-of-service class for tasks that prevent the user from actively using your app.

case `default`
The default quality-of-service class.
case utility
The quality-of-service class for tasks that the user does not track actively.

case background
The quality-of-service class for maintenance or cleanup tasks that you create.

case unspecified
The absence of a quality-of-service class.

global (qos :)

큐와 연관시킬 서비스 품질 레벨. 이 값은 시스템이 작업 실행을 예약하는 우선 순위를 결정합니다. 가능한 값 목록은 DispatchQoS.QoSClass를 참조하십시오.

DispatchQueue.Attributes

디스패치 큐의 동작을 정의하는 속성.

concurrent (struct로 정의되어 있음)

The queue schedules tasks concurrently. 대기열은 작업을 동시에 예약합니다.

initiallyInactive

The newly created queue is inactive. 새로 작성된 큐가 비활성입니다.

나만의 큐

let myQueue = DispatchQueue(label: "my")

스크린샷 2020-03-21 오전 1 03 02

 let mineQueue = DispatchQueue(label: "bbb", attributes: .concurrent)
//명시적으로 지정해줌으로서 큐의 속성을 정의
//정의하지 않으면 Serial Queue