ios개발/프로젝트

<ios프로젝트2> GCD - Dispatch Queue 사용해 보자.

studying develop 2020. 3. 24. 02:28

[https://magi82.github.io/gcd-01/] 이게 깔금한거 같다.

 

DispatchQueue

GCD를 사용하기전에 먼저 알아야 할 클래스가 있습니다.

바로 DispatchQueue라는 클래스인데요.
실제로 해야할 Task를 담아두면 선택된 스레드에서 실행을 해주는 역할을 합니다.

DispatchQueue는 2가지로 종류로 나눌수 있습니다.
Serial Dispatch Queue Concurrent Dispatch Queue입니다.

  • Serial Dispatch Queue
    Serial Queue는 등록된 작업을 한번에 하나씩 차례대로 처리 합니다.
    처리중인 작업이 완료되면 다음 작업을 처리합니다.

  • Concurrent Dispatch Queue
    Concurrent Queue는 등록된 작업을 한번에 하나씩 처리 하지 않고
    여러 작업들을 동시에 처리합니다.

let serialQueue = DispatchQueue(label: "magi82.serial")
print(serialQueue)	// Serial Dispatch Queue

let concurrentQueue = DispatchQueue(label: "magi82.concurrent",
                                    attributes: .concurrent)
print(concurrentQueue)	// Concurrent Dispatch Queue

 

앱 실행시 시스템에서 기본적으로 2개의 Queue를 만들어 줍니다.
Main Queue Global Queue 입니다.

  • Main Queue
    메인 스레드(UI 스레드)에서 사용 되는 Serial Queue 입니다.
    모든 UI 처리는 메인 스레드에서 처리를 해야 합니다.

  • Global Queue
    편의상 사용할수 있게 만들어 놓은 Concurrent Queue 입니다.
    Global Queue는 처리 우선 순위를 위한 qos(Quality of service)
    파라메터를 제공합니다.
    병렬적으로 동시에 처리를 하기때문에 작업 완료의 순서는 정할수 없지만
    우선적으로 일을 처리하게 할수 있습니다.

let mainQueue = DispatchQueue.main
print(mainQueue)	// Main Queue
let globalQueue = DispatchQueue.global(qos: .background)
print(globalQueue)	// Global Queue

QOS 우선순위는 아래와 같습니다.

  1. userInteractive
  2. userInitiated
  3. default
  4. utility
  5. background
  6. unspecified

 

 

sync / async

Dispatch Queue는 sync와 async라는 메소드를 가지고 있습니다.
동기, 비동기라는 말을 많이 들어 보셨을 겁니다.

sync는 동기 처리 메소드 입니다.
해당 작업을 처리하는 동안 다음으로 진행되지 않고
계속 머물러 있습니다.

 

async는 비동기 처리 메소드 입니다.
sync와는 다르게 처리를 하라고 지시후 다음으로 넘어가 버립니다.

 

간혹 가다가 오해하는 분들이 계신데
Serial / Concurrent와 sync / async 는 별개 입니다.
직렬인데 비동기 일수도 있고, 병렬인데 동기 일수도 있습니다.
직렬과 병렬은 한번에 하나만 처리하느냐 동시에 여러개 처리하느냐고
동기와 비동기는 처리가 끝날때까지 기다리느냐
지시만하고 다른 처리를 하느냐 입니다.

 

 

 

 


 

[https://zeddios.tistory.com/516]

 

이분 설명이 깔금하지 않는데, 이해하기 쉽게 되있다.

 


이건 영어로 되어 있지만 이게 notify, enter, leave, barrier등을 그림으로 이해하기 쉽게 해놓았다. [https://medium.com/@aliakhtar_16369/concurrency-in-swift-grand-central-dispatch-part-2-1b0b025ee381]

 


 

읽고 새로 안 부분은 qos에 관한 부분이다. qos = quality of service이다.

 

 

 

[https://zeddios.tistory.com/521] 이건 다른 글에 쓰셨네.

Choosing a Quality of Service Class

시스템은 QoS정보를 사용하여 스케쥴링, CPU 및 I/O처리량 및 타이머 대기 시간과 같은 priority를 조정합니다. 결과적으로 수행된 작업은 성능과 에너지 효율성 간의 균형을 유지합니다. 

task에 QoS를 할당 할 때, 사용자에게 미치는 영향과 다른 작업에 미치는 영향을 고려하세요. 다음에서 볼 수 있듯이, 4개의 primary QoS class가 있으며, 각 level은  작업 중요도에 해당됩니다.

 

User-interactive : main thread에서 작업, 사용자 인터페이스(UI) 새로고침 또는 애니메이션 수행과 같이 사용자와 상호작용 하는 작업입니다. 작업이 신속하게 수행되지 않으면, UI가 중단된 상태로 표시될 수 있습니다. 반응성(responsiveness)과 성능(performance)에 중점을 둡니다.

Duration of work to be performed(수행해야될 작업의 기간?) - 순식간에 끝난다.(Work is virtually instantaneous.)

 

 

User-initiated : 사용자가 시작한 작업이며, 저장된 문서를 열거나, 사용자 인터페이스에서 무언가를 클릭할 때 작업을 수행하는 것과 같은 즉각적인 결과가 필요합니다. 사용자 상호작용을 계속하려면 작업이 필요합니다. (The work is required in order to continue user interaction) 반응성과 성능에 중점을 둡니다. 

Duration of work to be performed : 거의 순식간이며, 몇 초 또는 그 이하입니다.

 

Utility : 작업을 완료하는 데 약간의 시간이 걸릴 수 있으며, 데이터 다운로드 또는 import와 같은 즉각적인 결과가 필요하지 않습니다. 유틸리티 작업에는 일반적으로 사용자가 볼 수 있는 progress bar가 있습니다. 반응성, 성능 및 에너지 효율성 간에 균형을 유지하는 데 중점을 둡니다. 

Duration of work to be performed : 작업은 몇초에서 몇분정도가 걸립니다. 

 

Background : 백그라운드에서 작동하며, indexing, 동기화 및 백업과 같이 사용자가 볼 수 없는 작업. 에너지 효율성에 중점을 둡니다.

Duration of work to be performed : 작업은 분(minutes) 또는 시간(hour)과 같은 상당한 시간(significant time)이 걸립니다.

 

중요 : 최적으로는, 사용자 작업이 발생하지 않는 시간의 90%이상을 Utility QoS level에서 실행하는 것이 좋습니다.


이제 내가 실험해 본 부분은 , 네트워크 연결을 background를 먼저 10개하고, userinitiated를 1번 했다. 그랬더니 

 

entering background
entering background
entering background
entering background
entering background
entering background
entering background
entering background
entering background
entering background
its in background queue
its in background queue
its in background queue
its in background queue
entered NextVC
its in background queue
its in background queue
its in background queue
its in background queue
its in background queue
its in background queue
its in userInitiated queue

background 작업 진입을 10번 신청했는데, 앞에4개가 처리되던 중간에 entered NextVC로 userInitiated 작업을 신청해도 백그라운드 작업이 다 완료되고 나서야 수행된다......

 

내가 원한건 작업 10개를 수행하다, 중요한 작업 1개 들어오면 선행 작업은 중지하고, 후행 작업이 먼저 수행되기를 바란다.

 


[https://developer.apple.com/documentation/dispatch/dispatchgroup/2016090-wait]

Instance Method

wait()

Waits synchronously for the previously submitted work to finish.

 

왠지 이거 사용하면 중지 할 수 있지 않을까?

 

음 아닌거 같다. [http://seorenn.blogspot.com/2015/08/swift-dispatch-group.html]

 

웨잇은 그냥 그룹내의 앞선 두 타스크 모두가 끝나길 기다리는 것이다.


Swift의 GCD 사용법

 

[https://usinuniverse.bitbucket.io/blog/gcd.html] 여기는 프로세스,스레드 그리고 멀티 스레드 멀티 프로세스, concurrency parallelism, 동기 비동기를 먼저 설명해 준다.

 

[https://kka7.tistory.com/147] 여기는 GCD 예제가 많다. 게다가, 세마포에 대한 사용을 언급했다.

 

세마포로 내 문제가 해결 되나?.. 우선순위가 높은 작업이 먼저 안된다. 네트워크 연결중이라 그런가?? 그냥 리스폰스 안보내고, 나중에 첨부터 다시하면 되지 않나.

 

아니 근데 우선순위 높은게 있으면 먼저 해야되는거 아닌가? -> 일단 이걸 알아 보자.

 

그냥하지 않는게 좋겠다.????

 


디스패치 큐에 우선순위가 더 높은 태스크가 들어오면 어떻게 되는지!!