본문 바로가기

iOS

[iOS] DispatchGroup, DispatchItem, DispatchSemaphore

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로 넘어갈 수 있는 기능을 사용! 한 것 같습니다.

 

 

참고

 

 

Medium

 

sujinnaljin.medium.com

 

 

후기

 

데드락 조심하라구 5252

메인 스레드에서 조심하라고 wait() 5252