Dispatch WorkItem은 task를 캡슐화 시키는데 사용하며
Dispatch Group는 task 그룹을 모니터하는데 사용합니다.
사용도 어렵지 않고, 형식도 dispatch queue와 비슷해, 자세한 설명은 공식문서 링크로 대체하고
저는 제 플젝에 사용한 예제를 포스팅하겠습니다.
Dispatch work group
developer.apple.com/documentation/dispatch/dispatchgroup
Dispatch work item
developer.apple.com/documentation/dispatch/dispatch_work_item?language=occ
최초 코드
DispatchQueue.global().async {
while(true){
var s: Int = Int.random(in: 1...3)
if race.setArr(index: 0, run: s) {
break
}
s = Int.random(in: 1000000...3000000)
usleep( UInt32(s) )
}
}
위 코드는 경주에 달리는 말 중 한마리의 역할을 수행합니다.
race.setArr은 index번째 말이 s만큼 달려서 10칸을 다 달렸다면 false를 반환해 반복문을 제어합니다.
저는 말이 4마리부터 20마리가 뛰는 상황이 필요했습니다. 그때마다 스레드를 저렇게 만들어야 되나? 싶었습니다.
두번째 코드
for i in 0..<numOfHorse {
setHorse(horseNum: i, race)
}
func setHorse(horseNum i:Int, _ race: Race){
var isEnd: Bool = false
DispatchQueue.global().async{
while(true){
var s: Int = Int.random(in: 1...3)
if race.setArr(index: i, run: s) {
break
}
s = Int.random(in: 1000000...3000000)
usleep( UInt32(s) )
}
}
}
그래서 원하는 수에 맞게 동적으로 생성되게 만들었습니다.
근데 뭔가 지저분합니다. 들판에 목줄없이 강아지를 풀어놓은것 같습니다.
캡슐화
dispatch group와 dispacth work item을 사용해 보겠습니다.
let raceGroup = DispatchGroup.init()
let raceQueue = DispatchQueue(label: "raceQueue", attributes: .concurrent)
for i in 0..<numOfHorse {
let horseQueue = setHorse(horseNum: i, race, raceGroup)
raceQueue.async(group: raceGroup, execute: horseQueue)
}
func setHorse(horseNum i:Int, _ race: Race , _ group: DispatchGroup) -> DispatchWorkItem{
let runHorse = DispatchWorkItem{
while(true){
var s: Int = Int.random(in: 1...3)
if race.setArr(index: i, run: s) {
break
}
s = Int.random(in: 1000000...3000000)
usleep( UInt32(s) )
}
}
return runHorse
}
sethorse메서드를 사용해 dispatchWorkItem객체를 생성해 하나의 dispatch queue인 raceQueue에 부착해 실행했습니다.
그리고 raceQueue는 raceGroup에서 실행되어서 모니터까지 가능합니다.
raceGroup.notify(queue: raceQueue) {
print("레이스 스레드 수행완료")
exit(EXIT_SUCCESS)
}
종료시에 작업도 수행할 수 있구요.
저는 그룹에 하나의 디스패치 큐만 있었지만, Dispatch Group는 다수의 dispatch queue를 수용가능합니다.
참고로 workGruop의 notify는 runloop가 돌고있는 상황에서 스레드는 종료가 아니라 '대기'이기 때문에 작동하지 않습니다.
runloop이 종료되고 스레드가 종료되야 nofity가 실행됩니다.
다음엔 제 경주 코드 예제를 전체를 들고오도록 하겠습니다.
'Language > Swift' 카테고리의 다른 글
[Swift] 고차함수 Map, Filter, Reduce (0) | 2021.04.05 |
---|---|
[Swift] GCD로 경마 구현해보기 (0) | 2021.03.24 |
Swift GCD(Grand Central Dispatch) [4] - RunLoop 실행과 종료 (0) | 2021.03.23 |
Swift GCD(Grand Central Dispatch) [3] - 예제 사용해보기 (0) | 2021.03.22 |
Swift GCD(Grand Central Dispatch) [2] - DispatchQueue (0) | 2021.03.22 |