Dispatch Group의 목적!!!!
여러 스레드로 분배된 작업들이 끝나는 시점을 그룹지어서 한번에 파악하고 싶을 때 Dispatch Group의 사용됩니다.
(예를 들어 셀의 모든 이미지가 다운로드 된 뒤에 특정 행동을 해야할 때)
사용방법
1. notify() 사용!
출력은?!?!
.
.
.
2초 후
이렇게 두개의 task가 다 끝났을 때 notify()를 통해 알 수 있습니다.!
let group = DispatchGroup()으로 만들 수 있음
2. group.wait() 사용
wait를 쓰면 2개가 다 끝날 때 까지 멈춰있기 때문에 잘못쓰면 데드락 발생합니다.
안쓰는게 나아보이는데??!?!?!?! 최대한 notifify를 쓰는게 나은 것 같습니다.
(+wait에 시간 파리미터를 줘서 그 시간 넘으면 task는 따로 처리하고 메인 task는 바로 이어서 동작하는게 있긴함)
3. 비동기안의 비동기 (enter(), leave())
비동기안의 비동기라는게 이런 경우인데 비동기는 스레드에서 queue에 일 넣고 다음 task를 실행 시키는 것인데. 다음 task가 그냥 task의 끝이라면... notify는 일을 다 처리했다고 처리하여 "끝"을 바로 출력하게 됩니다.
enter() 메서드와 leave() 메서드를 사용해 볼까요!!
짠 이렇게 비동기로 들어가기전에 enter() 비동기 task가 끝날 때 leave() 메서드를 짝지어 사용하면 됩니다.!
enter()으로 +1 해주고 leave()로 -1 해주면서 notify 조건을 충족시켜주는 것 같아요. ㅎ
DispatchWorkItem
지금까지 task를 클로저를 통해서 실행시켰는데요!
사실 그 클로저는 DispatchWorkItem 클래스로 처리할 수 있습니다.
"응 그렇게 해도 돼"
DispatchWorkItem은 qos설정이나 원래 있던 설정들을 다 가지고 있습니다.
추가적인 기능은
1. 취소
.cancel() 메서드로 작업을 취소 가능합니다.! 이미 시작한건 DispatchWorkItem 속성 inCancelled가 true가 됩니다.
2. 다음 차례지정 (completion 같은 기능)
notify(queue:execute:) 메서드를 통해 DispatchWorkItem을 끝낸뒤 다음에 원하는 queue로 excute로 원하는 task를 실행!!
DispatchSemaphore
동시 작업 개수 제한!!! 한번에 수행할 수 있는 작업의 수를 제한하는 것
(기존에 제가 C언어에서 알던 semaphore와 비슷합니다.)
let semaphore = DispatchSemaphore(value: 2)이렇게 쓴다. (2개로 제한)
임계구역 들어갈 때는 wait() , 나올 때는 siginal() 호출 !!!
쉽게 생각하면 value를 wait는 -1, signal은 +1 시켜줍니다.
제가 생각했을 때 특이하게 쓰는 방법이 DispatchSemaphore(value: 0) 이렇게 쓰고
특정 작업이 끝날때 semaphore.signal() 해서 value +1해주고
그밑에
semaphore.wait()해서 태스크 끝날 떄까지 기다렷다가 실행시킬 수 있습니다.
(이거 C언어로 프로세스끼리 특정 체크해줄때 이렇게 했었는데...)
아마 wait는 value가 1이상일때를 계쏙 기다렸다가 1이상이 되면 사용되면서 다음 task로 넘어갈 수 있는 기능을 사용! 한 것 같습니다.
참고
후기
데드락 조심하라구 5252
메인 스레드에서 조심하라고 wait() 5252
'iOS' 카테고리의 다른 글
[iOS] SwiftLint 사용 (1) | 2021.05.04 |
---|---|
[iOS] 키보드에 맞게 view 수정, NotificationCenter, UIResponder (0) | 2021.04.12 |
[iOS] Dispatch Queue 종류 (0) | 2021.04.10 |
[iOS]동시성 프로그래밍, GCD, 동기, 비동기, 직렬성 (0) | 2021.04.10 |
[iOS] updateCycle (0) | 2021.04.07 |