티스토리 뷰


메인큐에서 sync 함수를 호출하게 되면 나는 오류입니다.



쓰레드를 좀 더 찾아보면 다음과 같은 화면을 볼 수 있습니다.



사진2


"BUG IN CLIENT OF LIBDISPATCH: dispatch_sync called on queue already owned by current thread"


쓰레드가 일을처리하다가 sync를 만났다. 네 데드락입니다.


Apple 에서도 얘기하듯이 메인 큐에서 sync하게 task를 시키면 데드락이 발생한다고 합니다.


mainQueue는 main thread관리하는 serial queue입니다.  serial queue로 같은 상황을 만들어보겠습니다.


        let serialQueue = DispatchQueue(label: "serial")

        

        serialQueue.async { // outer

            

            serialQueue.sync { // inner

                

            }

        }


[Thread] ----inner-otuer--->


여기서 outer가 sync, async인지 보다 inner가 sync인게 중요합니다.


outer가 sync로 실행하든 async로 실행하든 일단 실행하면 끝나야 합니다.


하지만 outer가 끝나려면 inner가 끝나야합니다. inner는 sync로(순차적으로) 실행되기 때문에 outer가 끝나야 시작됩니다.


따라서 서로 끝나기를 기다리는 무한 대기 상태(데드락)에 빠집니다.


DispatchQueue.main.sync는 위 예시처럼 중첩으로 사용하지 않았는데 왜 그럴까요?


iOS에서는 기본적으로 Thread를 지정하지 않으면 main thread에서 실행됩니다.


따라서 명시적으로 쓰레드 지정하지 않고 DispatchQueue.main.sync 를 쓴다면 ( IBAction나 viewdidload 메소드 등 안에서 )


위 예시와 같은 모양이 됩니다.


     DispatchQueue.main.async { // outer 

            DispatchQueue.main.sync { // inner

                

            }

        }



따라서 위와 같이 데드락이 발생하게 됩니다.


사실 사진2에서 나오는 것 처럼  Debug Navigator - Thread 내역을 보면 바로 확인 할 수 있습니다.


apple에서 만든 main thread ( serial )

0. 끝날때 까지 기다려야겠네. 

1 sync가 불렸네

2 viewDidLoad함수에서





     DispatchQueue.main.async { // outer  async? sync?

            DispatchQueue.main.sync { // inner

                

            }

        }


마지막으로 위 사진에서 outer는 시스템에서 호출하는 부분이라서 임의로 async했지만 때에 따라서 async일 수도 sync일 수도 있을 것 같습니다. vc life cycle 처럼 순서가 있는 것들은 sync로 IBAction은 같이  순서가 없는 것들은 async로 처리 하는 것 같습니다.

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함