Dispatch Group 이란?

brick·2023년 2월 28일
0

Concurrency Programming

목록 보기
4/6
post-thumbnail

Dispatch Group 이란?

작업들의 그룹을 만들고 각 그룹별로 끝나는 시점을 알고싶을때 사용한다.

ex) 여러 애니메이션 효과들이 모두 종료된 시점을 알고 싶을 때, 런치스크린에서 첫 화면 넘어가기 전에 모든 이미지들이 다운 완료해야 할 때

let group1 = DispatchGroup()
DispatchQueue.global().async(group: group1) { }
DispatchQueue.global().async(group: group1) { }
DispatchQueue.global().async(group: group1) { }
            
group1.notify(queue: DispatchQueue.main) { [weak self] in
	self?.textLabel.text = "모든 작업 완료!!"
}



Dispatch Group Wait

  • 디스패치 그룹에서 wait메서드를 사용하면 모든 작업이 완료 될 떄까지 현재 대기열을 동기적으로 차단할 수 있다.
  • timeout 파라미터를 사용해서 얼마나 기다릴지 정할 수 있다.(설정하지 않으면 무제한 대기)
  • main 쓰레드에서 사용하면 안 된다.(main 쓰레드 block되면 UI 멈춘다.)
let group1 = DispatchGroup()
DispatchQueue.global().async(group: group1) { }
DispatchQueue.global().async(group: group1) { }
DispatchQueue.global().async(group: group1) { }
            
group1.wait(timeout: DispatchTime.distantFuture)             
let group1 = DispatchGroup()
DispatchQueue.global().async(group: group1) { }
DispatchQueue.global().async(group: group1) { }
DispatchQueue.global().async(group: group1) { }
            
if group1.wait(timeout: .now() + 60) == .timeOut {
	print("작업이 60초안에 종료하지 않았습니다.")
}



그룹 클로저에서 비동기 함수를 호출할때 문제

let group1 = DispatchGroup()
            
DispatchQueue.global().async(group: group1) {
                
	print("async start")
	asyncMethod(input: url) { result in
                
	}
	print("async finish")
}

비동기 함수때문에 잘못된 시점에서 group이 끝났다고 생각할 수 있다.


enter(), leave() 메소드를 사용해서 시작 시점과 끝나는 시점을 명확하게 해준다.

let group1 = DispatchGroup()
            
DispatchQueue.global().async(group: group1) {
	group1.enter()
	asyncMethod(input: url) { result in
		group1.leave()
	}
}



Dispatch WorkItem

  • 큐에 제출하기 위한 객체 작업을 미리 정의해 놓고 사용한다.
  • 빈약한 취소 기능이 있다.
  • 빈약한 순서 기능이 있다.

사용법

let item1 = DispatchWorkItem(qos: .utility) {
	print("task1")
	print("task2")
}
            
let item2 = DispatchWorkItem {
	print("task3")
	print("task4")
}
            
let queue = DispatchQueue(label: "test")
queue.async(execute: item1)
queue.async(execute: item2)

취소 기능

  • 작업이 아직 시작 안된 경우(아직 큐에 있을 때)는 작업이 취소 된다.
  • 작업이 실행중인 경우는 isCancelled속성이 true로 설정되지만 실행중인 작업이 멈추지는 않는다.
let item1 = DispatchWorkItem(qos: .utility) {
	print("task1")
	print("task2")
}
            
let item2 = DispatchWorkItem {
	print("task3")
	print("task4")
}
            
item1.cancel()
            
let queue = DispatchQueue(label: "test")
queue.async(execute: item1)
queue.async(execute: item2)

순서 기능

  • notify메서드를 사용해서 다음에 실행할 작업을 지정한다.
let item1 = DispatchWorkItem(qos: .utility) {
	print("task1")
	print("task2")
}
            
let item2 = DispatchWorkItem {
	print("task3")
	print("task4")
}
            
item1.notify(queue: DispatchQueue.global(), execute: item2)
queue.async(execute: item1)


Dispatch Semaphore

공유 리소스에 접근가능한 작업 수를 제한할 때 사용한다

ex) 다운로드 숫자를 제한할 때

value: 접근가능한 작업 수
enter(), leave()를 사용해서 접근제한 통제한다.

let semaphore = DispatchSemaphore(value: 3)
queue.async(group: group1) {
	group1.enter()
	semaphore.wait()
	asyncMethod {
		group1.leave()
		semaphore.signal()
	}
}



참고

0개의 댓글