• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    미해결

GCD 질문입니다.

22.01.05 13:47 작성 조회수 143

2

dispatchqueue.global().async 안에 dispatchqueue.global().sync를 하면 교착이 걸릴 수 있어서 안해야한다고 말씀하셨는데요, 제가 이해한 부분이 맞는지 봐주시겠습니까..

 

main thread에서 dispatchqueue.global().async 를 발견해서 예를들어 gcd에서 task를 thread3에 주고 기다리지않고(async) 곧 바로 return 하였습니다. 그런데 우연히 그 task의 내부인 task(sync)가 thread3에 할당되었습니다.

1. 기다리지 않는다고 했는데 기다려야하는 일이 혼선되어 데드락이 일어나는 것인가요? 

2. 처음에 async task가 thread3에 배정된 상태인데, 그 thread3에서 global()을 부를 경우에도 동인한 쓰레드(thread3)로 배정될 수 있나요?

답변 1

답변을 작성해보세요.

0

네 한규님 안녕하세요!

말씀하신 대로
Dispatchqueue.global() 큐라고 가정하고...
그리고 작업(task)이 2개 있다(task1, task2)고 해볼께요.
아래같은 코드를 가정하는 것이죠.

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


그러면..  글로벌큐는.. 예를 들어 2, 3, 4번 쓰레드를 사용하는 큐가 되겠죠.

이제 메인쓰레드에서 글로벌큐로 작업을 보내면,
일단 작업 task1과 task2가 그 중 하나인 3번 쓰레드에 배치될 수 있습니다.
(그냥 일단 둘다 3번 쓰레드에 배치된다고 가정을 해보는 것이죠.)

그러면 아래 같은 그림이 될 것 같습니다.

(일단 하나의 클로저에 묶여 있으니 사실상 하나의 작업으로 인식되고 3번쓰레드에만 배치되는 것이 옳겠죠.)


여기서 task1 은 먼저 비동기이니.. 리턴(return)을 했는데..

자, 이제 여기서.. 글로벌큐로 동기적으로 task2를 다시 보냅니다.
재배치를 해야하겠죠, 그러면 아래 그림처럼 될 것 같아요.


여기서 이제 두번째(task2) 작업을
동기적
(sync)으로 보내면서 기다릴꺼야 라고 하겠죠.
(2, 4번에 배치될 수도 있지만 3번에 배치될 수도 있는 상황이 있을 수도 있습니다.)

그러면 어떻게 될까요?

3번 쓰레드에서 3번쓰레드로 동기적으로 보내는 일이 일어납니다.
즉, 3번쓰레드에서 작업(task)을 보내서 그 작업을 기다리겠다고 했는데.. 나한테 작업이 다시 할당이 된거예요.
나(3번 쓰레드)는 지금
(1) 기다리는 일을 하고 있는데
(2) 새로운 일이 재배치가 된거죠.




그래서... 이러지도 못하고 저러지도 못하는.. 데드락의 상태가 되는 겁니다.

질문하신 것의 순서에 따라 다시 답변을 드리면..
1. 기다리는 쓰레드(다른 작업이 못하게 막힌 쓰레드)에 다시 작업이 배치되어서.. 일이 아예 진행이 안되는 상태가 되는 것입니다.

2. 네 다시 동일한 쓰레드(3번 쓰레드)에 배치될 수 있어요. 왜냐면, 큐(대기열) 입장에서는 현재 어떤 쓰레드가 작업중인지는 모를 수 있기 때문에 동일한 쓰레드에 일이 배치될 수도 있습니다. 그래서.. 항상은 아니지만, 그런 가능성을 항상 안고 있기 때문에, 일처리가 아예 중단되는 데드락의 상황이 발생할 수 있게 되는 겁니다!


혹시 이해 안되시면 다시 질문 주세요 :)

고맙습니다.