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

sujinnaljin님의 프로필 이미지
sujinnaljin

작성한 질문수

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

5강의 2번째 유의 사항 (현재의 큐에서 현재의 큐로 동기적으로 보내면 안됨) 관련 질문입니다.

작성

·

265

1

안녕하세요 앨런님 :) 5강의 2번째 유의 사항인 "현재의 큐에서 현재의 큐로 동기적으로 보내면 안됨" 관련해서 두가지 질문이 있습니다

1. 2번째 유의 사항 - 데드락 발생 가능성 때문에 현재의 큐에서 현재의 큐로 “동기적”으로 보내면 안된다라고 말씀 주셨는데, 메인 스레드에서 DispatchQueue.main.sync { } 를 하면 안되는 것도 같은 이유에서일까요??

2. “현재의 큐”에서 “현재의 큐”로 동기적으로 보내면 안된다는 것에서 현재의 큐가 무엇을 말하는지 명확하게 와닿지 않습니다. 일단 같은 객체를 말씀하는 것은 아닌 것 같구요,,!

무조건 메인 스레드에 작업을 할당하는 메인 큐를 제외하고는 글로벌 큐, 커스텀 큐 모두(Qos 무관) 어느 스레드에 작업을 할당할지 알 수 없기 때문에  

customQueue.async {

  globalQueue.sync { }

}

이런 상황에서도 데드락의 위험은 있을 것 같습니다. 

따라서 말씀하신현재의 나누는 기준은 메인 vs not 메인 되는 걸까요?

감사합니다!

답변 6

1

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

https://developer.apple.com/documentation/dispatch/dispatchqueue/2300077-global

에서 보시면

Qos에 따라 각각 다른 글로벌큐 객체를 생성합니다. ^^

네, 그래서 각각 다른 Qos 큐라면 쓰레드가 겹칠일이 없는 것(데드락 가능성 없음)이기도 하고요! 큐 객체에 따라 우선 순위를 관리하니 일이 먼저 끝나도록 조절한다고 보시면 될 것 같아요ㅎㅎ

그래서...

DispatchQueue.global().async { DispatchQueue.global().sync } 

이런 경우는 같은 큐(현재의 동일한큐) 이므로 데드락 가능성 발생, (디폴트 글로벌큐가 동일한  2,3,4번 쓰레드를 사용하니.. 쓰레드 겹칠 가능성 있음)

그러나,

DispatchQueue.global(qos: .utility).async { DispatchQueue.global().sync } 

이런 경우는 유틸리티 디폴트 글로벌큐는 2,3 번 쓰레드 적절하게 사용, 디폴트 글로벌큐는 4, 5,6 번 쓰레드 적절하게 사용(했다가 없어짐)이므로,  데드락의 가능성이 없는 것입니다 ^^

고맙습니다. :)

1

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

오 자세한 설명 감사합니다! DispatchQueue.global() 로  다른 gloabl 큐 객체를 각각 생성해주는걸로 이해했어요.. 근데 같은 객체를 지칭하는거였나 보군요,,🤔🤔 

그럼  DispatchQueue.global().async { DispatchQueue.global().sync } 에서 큐가 서로 같은 객체일때

DispatchQueue.global(qos: .utility).async { DispatchQueue.global().sync } 의 큐는 각각 다른 객체인가요 같은 객체인가요? (즉 QOS에 따라 객체가 달라지는건지...???)

1

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

안녕하세요! 수진 님ㅎㅎ

1.네 정확하게 맞습니다. DispatchQueue.main.sync { } 를 하면 안되는 이유가 동일합니다. 즉, 저 코드는 (원래 진행되고 있던) 작업을 메인쓰레드에서 메인쓰레드로 보내서 기다리기 때문에, 데드락이 걸립니다. (보낸쓰레드에서 기다릴 것이라고 보냈는데, 다시 그 해당쓰레드에 배정이 되어버리니 아무것도 진행되지 못하는 상태가 되어버리는 것이예요.ㅎㅎ)

2. 현재의 큐는 동일한 큐 객체를 말하는 것이 맞습니다. 즉, global큐면 global큐, 커스텀큐라면 동일한 커스텀큐를 말하는 것입니다. (제가 그림과 코드도 넣어놓았는데용ㅠㅠㅠ?)


그리고, 조금 아래서 말씀하신

customQueue.async {

  globalQueue.sync { }

}

이런 상황에서 데드락의 가능성은 없습니다. 이 부분을 이제 좀 자세하게 말씀드려야 할 것 같은데요.. 제 PDF자료의 73페이지를 보시면 그래서, 제가 일부러 그림을 아래와 같이 넣어놓았습니다.

이렇게 위의 그림처럼 넣어놓은 이유는 예를 들어서

1) 디폴트 글로벌큐는  쓰레드 2, 3번만 사용,

2) 백그라운드 글로벌큐는 쓰레드 4,5번만 사용 이런식으로 진행이 됩니다.

그래서 각 큐에서 할당하는 쓰레드가 겹칠일은 없습니다 ^^ 

그리고 수진 님께서 깊게 공부하고 계시니,

이 내용을 조금만 더 설명 드리자면.. 
(오히려 헷갈리는 개념이 될 수 있어서.. 제 강의에서는 자세하게 말씀드리지 않고, 쓰레드 2이상의 쓰레드가 계속 존재하는 것처럼 표현을 해놓았지만, 그것은 아니고.. 쓰레드도 실은 객체의 개념입니다. 생성과 소멸이 존재합니다.)


"쓰레드도 객체이다."

아실 것 같긴한데, 이 내용을 조금 설명드릴께요.
일단은 실제 CPU 코어에 있는 하드웨어적인 쓰레드가 있고, 우리가 앱을 실행할때 운영체제에서 생성하는 소프트웨어적인 쓰레드의 개념이 있습니다. (참고: https://youtu.be/_dhLLWJNhwY)  (5분 20초정도 전후 2분~ 3분정도 참고)
(그리고 제가 그림을 그려서 강의에서 표현한 부분들은 사실 소프트웨어적인 쓰레드 입니다. )

실제로 앱이 실행되면 운영체제는 하드웨어의 쓰레드를 가져다가 소프트웨어적인 쓰레드 풀(여러개의 쓰레드 객체)을 만들어 놓고, GCD에서 사용하면서 실제로는  필요한 소프트웨어적인 쓰레드를 생성했다가 필요없으면 없애고 하는 활동을 합니다. 구글에서 "쓰레드풀"이라고 검색해보시면 자료가 많이 나오고.. 
예시: https://www.wrapuppro.com/programing/view/jAuG3VNBCbGnQWU
(위는 자바로된 자료이긴 합니다만, 원래는 쓰레드풀이라는 개념이 있다는 핵심적인 내용만 아시면 됩니다.)


어쨌든 이 모든 내용은 실제로 GCD나 Operation큐에만 작업을 넘기면 알아서 해주니까,
단순하게 쓰레드도 사실은 객체이고, 쓰레드풀이라는 개념이 있구나 하는 정도만 아시면 될 것 같아요!

그리고 제가 이 내용을 말씀드린 이유는 그래서...

결론적으로 말씀하신

customQueue.async {

  globalQueue.sync { }

}

이 코드에서 정확하게는 2번 3번 이런 쓰레드의 개념(이건 제가 강의를 쉽게 하기 위해 번호를 붙인 것 뿐임)이 아닌 여러개의 쓰레드 중에서 각 큐에서 사용하고있는 쓰레드 객체는 정해져 있기 때문에 데드락이 걸리지 않는다는 것입니다 ^^

한번 살펴보시고 그래도 궁금증이 안 풀리시면 다시 질문 주세요! 

감사합니다. :)

0

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

아이고 아닙니다! 공부하시는 스타일에 따라 다르긴 하겠지만, 뒤쪽에 더 중요한 내용도 많이 나오고! 두번보았을때, 이해가 더 잘된다고 하신 분들도 많아서 말씀드린거예요^^

화이팅입니닷. :)

0

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

아하 자세한 설명 감사합니다 ㅎㅎ 저는 하나가 이해 안되면 다른 것도 이해가 안돼서 그때 그때 파고 들어 공부하곤 하는데, 앞으론 조언 주신대로 질문은 메모 해놨다가 쭉 한번 듣고 크게 이해해보려고 노력하겠습니다! ㅎㅎ 조언 감사해요!

0

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

앗, 그리고.. 수진님! 제 강의를 보시면서 한 강의 한 강의 다 깊게 이해하시려는 것보다는.. 일단은 최소 1부 GCD까지는 1.2배속이든 1.5배속이든 한번 쭈욱 보시고, 다시 돌아오셔서 자세하게 정리하시는 것이 나을 것 같아요^^ 왜냐하면, 뒤에 중요한 내용들이 더 많이 나오고.. 뒤쪽을 보다보면 자연스럽게 앞부분은 이해되는 내용들이 많답니다.ㅎㅎ

그리고 sync 메서드를 사용하는 경우 등등, 정말 뒤쪽에 중요한 내용이 더 많아요 ^^; 그래서.. 아무래도 큰 그림을 쭈욱 먼저 그리시고 자세하게 접근하시는 것이 조금 더 올바르지 않을까 추천드려요!

고맙습니다. :)

sujinnaljin님의 프로필 이미지
sujinnaljin

작성한 질문수

질문하기