GCD에 대해(DispatchWorkItem, DispatchSemaphore)

JinSeok Hong·2021년 10월 15일
0

Dispatch workItem


GCD에 대해서 마지막으로 알아볼 것은 DispatchWorkItem이다.
멀티스레드에 작업 자체를 클레스, 객체화해서 사용할 수 있는 방법이다.
우선 코드를 살펴보자!


let item1 = DispatchWorkItem(qos: .utility){
    print("task1")
} 

let item2 = DispatchWorkItem{
    print("task2")
} 

let queue = DispatchQueue(label : "mmm")

//method 1 (임의 순서)
queue.async(execute : item1)
queue.async(execute : item2)

//method 2 (순서 보장)
queue.async(execute : item1)
item1.notify(queue: DispatchQueue.global(), execute: item2) //item1 끝나고 item2 해라

이처럼 원하는 DispatchQueue에 원하는 작업을 객체화 시킨 뒤 넣어줄 수 있다. 또한 각 작업의 순서를 설정해줄 수 있다. 따라서 비동기 프로그래밍의 순서를 정해주는데 굉장히 좋을거 같다. 객체지향 프로그래밍의 장점에서 알 수 있듯이 작업을 객체화해서 사용하니 추상화, 캡슐화, 일반화, 다형성 측면에서 이점을 가져갈 것이다.

동시성 문제를 해결하고 가자!


아무래도 멀티스레드 환경에서 동시성을 사용한다면 '공유자원' 적인 측면에서 문제가 생길 수 있다.
먼저 Race Condition, 경쟁상황이 발생할 수 있다. 만약 두 개의 스레드가 같은 시간에 같은 데이터에 접근한다고 하자. 그러면 동일한 메모리 자원을 잡기 위해 서로 경쟁을 할 것이다. 이로 인해서 한 스레드의 작업의 결과를 반영하지 못한채 다른 스레드가 자원을 쓰며 정확한 데이터를 갖지 못할 수 있다. 또한 Deadlocks, 교착상태가 발생할 수 있다. 서로 막아놓은 자원에 접근하려 하면서 이러지도 저러지도 못하는 상황이 발생한다. 이로 인해 자원에 대한 비용이 증가하고, starvation, 무한 대기 등 여러 문제가 발생한다. 또한 Priority inversion 문제도 발생할 수 있다. 그렇다고 모두 순서를 보장해주기 위해 Serial한 형태로 모든 작업을 처리한다면 실행에 대한 효율성 측면이 안좋을 것이다. 그리고 앞서 말했던 네트워크 통신 시 동기성 프로그래밍으로 인한 UI 문제가 발생할 것이다. 그러면 iOS에서, 현재 배우고 있는 GCD에서는 이러한 문제점을 어떻게 해결할까?

DispatchSemaphore


이를 위해 GCD에서 제공하는 것이 있는데 바로 DispatchSemaphore이다. 바로 공유 리소스에 접근 가능한 작업의 수를 제한하는 것이다. 이러한 방식으로 리소스에 접근할 작업의 수를 지정해주는 것이다. 여기서 Semaphore는 공유 자원에 대한 접근을 제한하는 한 방법으로, 정수 변수로서 그 수를 지정해놓는 것이다. 스레드들이 자원의 베타적 사용을 보장받기 위해 critical section으로 들어가 일을 처리하고 나오면 시그널을 주는 그러한 방식이다.

let semaphore = DispatchSemaphore(value: 3) //3개만 접근하여 실행 가능하다.
queue.async(group: group1){
    group1.enter()
    semaphore.wait()
    asyncMethod{
        group1.leave() //끝나는 시점 알고 싶을 때
        semaphore.signal() //다 끝나면 시그널 
    }
}

0개의 댓글