인프런 커뮤니티 질문&답변

IOI님의 프로필 이미지

작성한 질문수

앨런 iOS Concurrency(동시성) - 디스패치큐와 오퍼레이션큐의 이해

3) 디스패치 배리어(Dispatch Barrier), 4) 객체 설계시 주의할 점

global()에서는 배리어가 동작하지 않는 것 같아요

해결된 질문

21.12.24 15:13 작성

·

161

2

아래는 제가 강의를 듣고 임의로 만들어본 예제입니다. concurrentQueue를 custom 큐로 만들어주면 잘 동작하는 반면 global()을 사용하면 배리어가 동작하지 않았습니다. 왜 이런건가요?

import Foundation

var shared: Int = 0

let group = DispatchGroup()

let concurrentQueue = DispatchQueue(label: "com.raywenderlich.number.isolation", attributes: .concurrent)

 

for _ in (1...30) {

  concurrentQueue.async(group: group) {

      print(shared, terminator: "")

  }

}

concurrentQueue.async(group: group, flags: .barrier) {

    print("")

    print("Barrier In")

    shared += 1

    sleep(3)

    print("Barrier Out")

}

for _ in (1...30) {

    concurrentQueue.async(group: group) {

        print(shared, terminator: "")

    }

}

 

group.wait()

 

답변 2

1

IOI님의 프로필 이미지
IOI
질문자

2021. 12. 25. 21:28

global()은 배리어로 제어할 스레드를 규정하기 어렵겠네요~ 이해되었습니다 감사합니다!

1

앨런(Allen)님의 프로필 이미지
앨런(Allen)
지식공유자

2021. 12. 24. 16:48

안녕하세요! IOI 님!

글로벌큐 같은 경우에는.. global 이라는 의미("전반적인/ 일반적인")에서 볼 수 있듯이 

원칙적으로는.. 비동기처리를 위해서, 편하게 막 가져다 쓰라고(?) 만들어 놓은 목적때문에

실제로는 OS에서 글로벌큐를 관리할때, 내부 쓰레드 객체들이 자주 바뀌기도 하고 그렇습니다.
(생겼다가 없어졌다가)
그리고 예를 들어서, 2~ 5번 쓰레드를 쓰다가.. 여력이 남으면 6 ~ 8번쓰레드로 사용하고... 등등 일반 글로벌큐는 약간 이런 특성이 있긴 있습니다.


그래서.. 특히나, "배리어 작업"에서만큼은 아예 특정한 목적에서 만들어 놓은 큐를 써야지 (내부 쓰레드 객체가 변하지 않고, 예를 들어 딱 정해진 2 ~ 5번 쓰레드만 사용) 원하시는 목적에 정확하게 동작하도록 설계가 가능하긴 합니다. :)


혹시나 내부 쓰레드 객체가 바뀌는 문제와 관련해서는.. 
바로 아래 아래 답변 중에 "Serial queue가 한개의 쓰레드를 사용한다는 내용에 질문..." 이 부분 대략적으로 읽어보시면 조금 도움이 될 것 같아요.


고맙습니다!

IOI님의 프로필 이미지

작성한 질문수

질문하기