ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [iOS] DispatchQueue.main.sync { } ๋Š” ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ• ๊นŒ?
    iOS/๐Ÿค– App 2021. 6. 7. 15:27

    ์„ ์ˆ˜์ง€์‹ : [iOS] GCD๋ž€?

     

     

    ์•ˆ๋…•ํ•˜์„ธ์š”๐Ÿถ

    ์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” GCD ๋ฅผ ์ฒ˜์Œ ๊ณต๋ถ€ํ• ๋•Œ

    ์‰ฝ๊ฒŒ์ดํ•ด๊ฐ€์ง€ ์•Š์•˜๋˜DispatchQueue.main.sync { } ์˜ ๋™์ž‘๋ฐฉ์‹์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

     

    StackOverflow ์—์„œ main ์“ฐ๋ ˆ๋“œ์— sync ๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ์•ฑ์ด ๊ฐ•์ œ์ข…๋ฃŒ ๋˜๋Š” ์ด์œ ๋ฅผ ์ฐพ์•„๋ณด๋ฉด,

    `Main queue์— sync๋กœ Task๋ฅผ ์ „๋‹ฌํ•˜๋ฉด Deadlock ์ด ๊ฑธ๋ฆฐ๋‹ค` ์ •๋„์˜ ๋ชจํ˜ธํ•œ ์ด์•ผ๊ธฐ๋งŒ ๋‚˜์™€์žˆ์–ด์„œ ์ œ๋Œ€๋กœ๋œ ์ด์œ ๋ฅผ ์•Œ๊ณ  ์‹ถ์–ด์„œ ํ•œ๋ฒˆ ์•Œ์•„๋ณด๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

     

     

    ์œ„์™€ ๊ฐ™์ด ์ง์ ‘ ์ž‘์„ฑํ•œ User Code ์—์„œ DispatchQueue.main.sync(block:) ์„ ํ˜ธ์ถœํ•˜๋ฉด ์•ฑ์— ํฌ๋ž˜์‹œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ๊ฐ•์ œ์ข…๋ฃŒ ๋ฉ๋‹ˆ๋‹ค.

     

    ์ด๋ฒˆ ๊ธ€์€ ์ด ํ˜„์ƒ์ด ์™œ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋Š”์ง€ ์•Œ์•„๋ณด๋Š” ๊ธ€์ž…๋‹ˆ๋‹ค.

     

    ๊ฒฐ๋ก ์„ ์šฐ์„  ๋ง์”€๋“œ๋ฆฌ๋ฉด

    ์•„์ง ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์€ Task ๊ฐ€ ์žˆ๋Š” SerialQueue ์— ๋™๊ธฐ์ ์œผ๋กœ Task๋ฅผ ์ „๋‹ฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

     

    ์šฐ์„  ๋‘ ๊ฐ€์ง€ ์‚ฌ์‹ค์„ ๋จผ์ € ์ดํ•ดํ•˜๋ฉด ์ˆ˜์›”ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.


     

    1. sync ์™€ async

    DispatchQueue.main.sync(block:),

    DispatchQueue.global().async(block:) ์œ„ ๋‘ ๋ฉ”์„œ๋“œ๋ฅผ ๋น„๊ตํ•˜๋ฉฐ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

     

    ๊ณตํ†ต์ 

    DispatchQueue.main.sync(block:),

    DispatchQueue.global().async(block:) ์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋“ค์€

    ํƒ€๊ฒŸ Queue ์— Task๋ฅผ ์ถ”๊ฐ€๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

    :: ์—ฌ๊ธฐ์„œ ํƒ€์ผ“  Queue ๋Š” Task ๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” Dispatch Queue ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

     

    ์˜ˆ๋ฅผ ๋“ค์–ด DispatchQueue.main.sync(block:) ๋Š” Main queue ์— ๋™๊ธฐ์ ์œผ๋กœ Task๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

     

    DispatchQueue.global().async(block:) ๋Š” Global queue ์— ๋น„๋™๊ธฐ์ ์œผ๋กœ Task๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

     

    Task๋ฅผ ์“ฐ๋ ˆ๋“œ์— ๋ฐฐ์ •ํ•˜์—ฌ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฒƒ์€ GCD์˜ ์—ญํ• ์ž…๋‹ˆ๋‹ค.

     

    ์ฐจ์ด์ : ๋ฐ˜ํ™˜ ์‹œ์ ๊ณผ ์™„๋ฃŒ ์‹œ์ 

    ์šฐ์„  async ๋กœ ์ „๋‹ฌํ•  ๊ฒฝ์šฐ, ๋น„๋™๊ธฐ ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์— Task๋ฅผ ํƒ€๊ฒŸ ํ์— ์ถ”๊ฐ€๋งŒ ํ•ด๋†“๊ณ  DispatchQueue.global().async(block:) ๋Š” ๋ฐ”๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

    ์ดํ›„ ์ถ”๊ฐ€๋œ Task๋Š” GCD๊ฐ€ ์•Œ์•„์„œ ์“ฐ๋ ˆ๋“œ์— ๋ฐฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ •ํ™•ํ•œ ์‹คํ–‰ ์‹œ์ ์„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

     

    ๊ทธ๋Ÿฐ๋ฐ sync ๋กœ ์ „๋‹ฌํ•  ๊ฒฝ์šฐ, ๋™๊ธฐ๋ฐฉ์‹์œผ๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ์— ์ถ”๊ฐ€๋œ ์ฆ‰์‹œ GCD Task๋ฅผ ์“ฐ๋ ˆ๋“œ์— ๋ฐฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ˆ˜ํ–‰์„ ์™„๋ฃŒํ•˜๊ธฐ ์ „๊นŒ์ง€ ํƒ€๊ฒŸ ํ์˜ ๋‚˜๋จธ์ง€ Task์— ๋ฝ์„ ๊ฑธ๊ณ , ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์„œ ์„ค๋ช… ๐Ÿ‘‡๐Ÿป๐Ÿ‘‡๐Ÿป๐Ÿ‘‡๐Ÿป)

     

    GCD๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋ฉ”์ธ ํ์— ์ถ”๊ฐ€๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๋ฉด, ์šฐ๋ฆฌ๊ฐ€ Task๋ฅผ ์‹คํ–‰ํ•  ์“ฐ๋ ˆ๋“œ๋ฅผ ์ง์ ‘ ์ง€์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค


     

    2. ๋ฝ์ด ๊ฑธ๋ฆฐ DispatchQueue ์˜ ๋™์ž‘

    Task๋ฅผ ๋™๊ธฐ์ ์œผ๋กœ(sync) ์ „๋‹ฌํ•˜๋ฉด GCD ๋Š” ์“ฐ๋ ˆ๋“œ์— Task ๋ฅผ ์ฆ‰์‹œ ๋ฐฐ์ •ํ•˜๊ณ  ๋ฐ˜ํ™˜๋˜๊ธฐ ์ „๊นŒ์ง€ ํƒ€๊ฒŸ ํ์— ๋ฝ์„ ๊ฒ๋‹ˆ๋‹ค.

     

    ๋ฝ์„ ๊ฑธ๋ฉด Queue ๋‚ด์˜ ๋‚˜๋จธ์ง€ Task๋Š” ๋ชจ๋‘ ์ •์ง€ ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. (= ์Šค๋ ˆ๋“œ๋ฅผ ๋ฐฐ์ •๋ฐ›์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.)

     

    ํ•ด๋‹น Task ๊ฐ€ ๋ฐ˜ํ™˜ํ•  ๋•Œ๊นŒ์ง€ Queue๋Š” ๋ฝ์ด ํ•ด์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

     

    ์ด์ œ ์•„๋ž˜์˜ ์ฝ”๋“œ์—์„œ ๋ธŒ๋ ˆ์ดํฌ ํฌ์ธํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹คํ–‰ํ•˜๋ฉฐ ํ์™€ ์“ฐ๋ ˆ๋“œ์˜ ์ƒํ™ฉ์„ ํ™•์ธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

     

    ์‹œ์ž‘ ์‹œ์ ์€ start(_:) ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ ์งํ›„ ์ž…๋‹ˆ๋‹ค.

     

    ์ด ๋•Œ ๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ (Thread 1) ์˜ ์Šคํƒ ํ”„๋ ˆ์ž„์„ ๋ณด๋ฉด start(_:) ๊ฐ€ ์ˆ˜ํ–‰ ์ค‘์ž„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์•„์ง ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ, serial queue ์ธ main queue์—์„œ ๋‹ค๋ฅธ Task ๋Š” ์ ˆ๋Œ€๋กœ ์ˆ˜ํ–‰๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

     

    ์ด ๋•Œ start(_:) ๋ฉ”์„œ๋“œ์—์„œ DispatchQueue.main.sync { print("Im main sync" } (์ดํ•˜ sync block) ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด sync block ๋ฐ˜ํ™˜๋˜๊ธฐ ์ „๊นŒ์ง€ ์ œ์–ด๊ฐ€ start(_:)๋กœ ๋‹ค์‹œ ๋„˜์–ด๊ฐ€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ์ „๋‹ฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

    ๋ฌธ์ œ๋Š” ์—ฌ๊ธฐ์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

     

    ๋ฉ”์ธํ๋Š” Serial Queue ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋จผ์ € ์ˆ˜ํ–‰๋œ start(_:) ๊ฐ€ ๋จผ์ € ๋ฐ˜ํ™˜๋˜์–ด์•ผ ๋‹ค์Œ Task ์ธ sync block์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์ฃ ?

     

    ๊ทธ๋Ÿฐ๋ฐ ํƒ€๊ฒŸ ํ์— lock์ด ๊ฑธ๋ ธ๊ธฐ ๋•Œ๋ฌธ์— ๋” ์ด์ƒ ์ž‘์—…์ด ์ง„ํ–‰๋  ์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

     

     

    ์ด ๋ฌธ์ œ๋Š” Main queue ๊ฐ€ Serial Queue ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š”๊ฒƒ์œผ๋กœ, Concurrent queue ์—์„œ๋Š” ์ถ”๊ฐ€๋œ Task๊ฐ€ ๋ฐ˜ํ™˜๋˜๊ธฐ ์ „๊นŒ์ง€ ์ด์ „์˜ Task๋ฅผ ๋ธ”๋ฝํ•˜๋Š” ๊ฒƒ์ด ๋ฌธ์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

     

    Serial queue์™€ ๋‹ฌ๋ฆฌ Concurrent queue๋Š” ์‹คํ–‰์ˆœ์„œ์™€ ๋ฐ˜ํ™˜ ์ˆœ์„œ๊ฐ€ ์ •ํ•ด์ ธ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

     


     

    ๊ทธ๋ ‡๋‹ค๋ฉด Main queue์— ์ˆ˜ํ–‰์ค‘์ธ Task๊ฐ€ ์—†๋‹ค๋ฉด

    Task๋ฅผ ๋™๊ธฐ๋กœ ์ „๋‹ฌํ•˜์—ฌ๋„ ๋ฐ๋“œ๋ฝ์€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์„๊นŒ?

     

    ์ œ๊ฐ€ ํ™•์ธํ•œ ๊ฒฐ๊ณผ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

     

    ๋‹ค์Œ ์˜ˆ์‹œ๋กœ ํ™•์ธํ•ด ๋ณผ๊ฒŒ์š”!!

    ์‹œ์ž‘ ์‹œ์ ์€ ์‚ฌ์šฉ์ž๊ฐ€ UIButton์œผ๋กœ .touchUPInside ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์„œ start(_:) ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค.

     

     

    ๋ธŒ๋ ˆ์ดํฌ ํฌ์ธํŠธ 32๋ผ์ธ์—์„œ async(block:)๋Š” ๊ธ€๋กœ๋ฒŒ ํ์— Task๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ฆ‰์‹œ ๋ฐ˜ํ™˜๋˜๊ณ , start(_:) ๋กœ ์ œ์–ด๊ฐ€ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค. ์ดํ›„ start(_:) ๋Š” ๋ฐ”๋กœ ๋ฐ˜ํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์— Main queue ์—์„œ๋Š” ๋” ์ด์ƒ ์ˆ˜ํ–‰์ค‘์ธ Task ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

    (๋‹ค๋ฅธ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฐ€์ •ํ•˜์—)

     

    ๋ธŒ๋ ˆ์ดํฌ ํฌ์ธํŠธ 33๋ผ์ธ์—์„œ, ์ด์ œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์“ฐ๋ ˆ๋“œ์—์„œ ๊ธ€๋กœ๋ฒŒ ํ์— ์ถ”๊ฐ€๋œ ๋ธ”๋Ÿญ (Task)์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    // ๊ธ€๋กœ๋ฒŒ ํ์— ์ถ”๊ฐ€๋œ ๋ธ”๋Ÿญ (Task) { DispatchQueue.main.sync { print("Im in main sync") } }

     

    ๊ทธ ๋ธ”๋Ÿญ์˜ ์ˆ˜ํ–‰ ๋‚ด์šฉ์€ Main queue์— ๋™๊ธฐ์ ์œผ๋กœ { print("Im in main sync") } ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

     

    ์•„๋ž˜ ์‚ฌ์ง„์„ ๋ณด์‹œ๋ฉด, Thread 1์€ ์Šคํƒ์—์„œ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๋Š” Task๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๋™๊ธฐ๋กœ ์ „๋‹ฌํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

     

    ๋จผ์ € ๋ฐ˜ํ™˜๋˜์–ด์•ผํ•  Task๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ”๋กœ ์‹คํ–‰ํ•˜๊ณ  ๋ฐ˜ํ™˜ํ• ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

     

    Main queue์— sync block์„ ์ „๋‹ฌํ•˜๊ธฐ ์ง์ „์ธ ์‹œ์ 

     

    Main queue์— ์ถ”๊ฐ€๋œ print("Im main sync block") ์„ ์ˆ˜ํ–‰ํ•˜๋Š” Main thread

     

    :: ๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ์—์„œ ํ•ญ์ƒ ์‹คํ–‰๋˜๋Š” main ์ด ์žˆ๋Š”๋ฐ, ์ด๊ฒƒ์€ ๋”ฐ๋กœ ๊ธ€๋กœ ์ž‘์„ฑํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. Debug navigator์— ์žˆ๋Š” ์ ์„ ์˜ ์˜๋ฏธ๋Š” ์•„์ง ์ฐพ์•„๋‚ด์ง€๋Š” ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

    :: Debug navigator์˜ ์•„์ด์ฝ˜์€ ๋ชจ์–‘๋ณ„๋กœ ์˜๋ฏธ๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ๋žŒ ๋ชจ์–‘์˜ ์•„์ด์ฝ˜์€ User Code๋ฅผ ์˜๋ฏธํ•˜๊ณ  ๋ณด๋ผ์ƒ‰ ์ปต ์•„์ด์ฝ˜์€ UIKit, AppKit ์ฝ”๋“œ์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

     

     

    ๋!

    ๋Œ“๊ธ€

์–ด์ œ๋ณด๋‹ค ๋ฐœ์ „ํ•œ ๋‚˜