티스토리 뷰

SerialQueue

순차 실행 작업을 계획합니다.

DispatchQueue의 attributes를 비워두면 serial이 됩니다.

let serialQueue = DispatchQueue(label: "serialQueue")

func serialQueueA() {
    
    serialQueue.async {
        print(#function, Thread.current)
        for i in 1...10 {
   
            print("❤️", i)
        }
    }
}

func serialQueueB() {
    
    serialQueue.async {
        print(#function, Thread.current)
        for i in 1...10 {
            print("💚", i)
        }
    }
}
serialQueueA()
serialQueueB()

serialQueue는 순차적으로 시행되므로 결과는 아래와 같습니다.

 

 

 

하나의 시리얼 큐를 더 만들어보겠습니다.

let serialQueue = DispatchQueue(label: "serialQueue")
let serialQueue2 = DispatchQueue(label: "serialQueue2")

func serialQueueA() {
    
    serialQueue.async {
        print(#function, Thread.current)
        for i in 1...10 {
            print("❤️", i)
        }
    }
}

func serialQueueB() {
    
    serialQueue.async {
        print(#function, Thread.current)
        for i in 1...10 {
            print("💚", i)
        }
    }
}
serialQueueA()
serialQueueB()


func serialQueueC() {

    serialQueue2.async {
        print(#function, Thread.current)
        for i in 1...10 {
            print("💛", i)
        }
    }
}

serialQueueC()

시리얼큐2는 첫 번째와 관련이 없습니다.

따라서 serialQueueA(), serialQueueB() 의 순서와 관계 없이 시행됩니다.

그리고 시리얼큐2는 다른 스레드에서 실행됩니다.

 

!! 테스트를 할 때, 항상 여러번 프린트해봐야합니다.

가끔 운좋게 모든 작업이 순차적으로 될 때도 있는데 항상 그렇다고 믿을 수 있기 때문입니다.

 

DispatchQoS.QoSClass

QoS는 다음과 같습니다.

 

userInteractive

- 시스템에서 가장 높은 우선순위, 애니메이션 UI등 사용자랑 상호작용

 

userInitiated

- 사용자가 앱을 액티브하게 사용하는 것을 막는 작업( prevent the user from actively using your app.)

- 사용자가 하는 작업에 대한 즉각적인 결과 제공

 

default

- 위 두 개보다 낮지만 utility나 background보다 높은 우선순위

 

utility

- default > utility > background

- 유저는 앱을 계속 사용가능

 

background

- 가장 낮은 우선순위

- 백그라운드에서 실행될때 작업 수행할 때 사용가능

 

테스트해볼까요?

let serialQueue = DispatchQueue(label: "serialQueue", qos: .userInteractive)
let serialQueue2 = DispatchQueue(label: "serialQueue2", qos: .default)

여러번 테스트해봤는데 노랑이 계속 더 늦게 끝납니다.

 

 

ConcurrentQueue

동시 실행 작업을 계획합니다.

let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)

func concurrentQueueA() {

    concurrentQueue.async {
        print(#function, Thread.current)
        for i in 1...10 {
            print("❤️", i)
        }
    }
}

func concurrentQueueB() {

    concurrentQueue.async {
        print(#function, Thread.current)
        for i in 1...10 {
            print("💛", i)
        }
    }
}
concurrentQueueA()

concurrentQueueB()

 

여러번 반복해보면 빨강이 먼저 끝나기도하고 노랑이 먼저 끝나기도합니다.

 

concurrentPerform(iterations:execute:)

싱글 블록을 디스패치 큐에 전달하고 iterations만큼 반복합니다.

이 메서드는 for루프를 효율적인 병렬 구현을 합니다.

var start = DispatchTime.now()
for i in 0..<100 {
    print(i, terminator: " ")
}
var end = DispatchTime.now()
print("\n")
print("for loop :", start.distance(to: end))


print("\n")
//반복순서가 중요하지 않을 때 속도 개선가능
start = .now()
DispatchQueue.concurrentPerform(iterations: 100) { i in
    print(i, terminator: " ")
}
end = .now()
print("\n")
print("concurrentPerform :", start.distance(to: end))

 

concurrentPerform은 자세히보면 숫자가 뒤죽박죽 되어있습니다.

for 루프에서보다 4배 이상 빠른 처리가 가능했습니다.

 

developer.apple.com/documentation/DISPATCH

 

Apple Developer Documentation

 

developer.apple.com

 

댓글
공지사항