๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
iOS

[iOS] iOS Concurrency - 1. GCD/Operation, ๋™๊ธฐ/๋น„๋™๊ธฐ, ์ง๋ ฌ/๋™์‹œ

by lizzydev 2023. 2. 11.

Inflearn: iOS Concurrency ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฐ•์˜ ์ •๋ฆฌ

1. GCD/Operation์— ์•ž์„œ

1) ์™œ ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ํ•„์š”ํ• ๊นŒ?

์“ฐ๋ ˆ๋“œ : ์ผํ•˜๋Š” ๋…€์„๋“ค

: ์•„์ดํฐ 11ํ”„๋กœ 6์ฝ”์–ด ( ์ผ์„ํ•˜๋Š” ๋…€์„์ด 6๊ฐœ๊ฐ€ ๋‹ฌ๋ ค์žˆ๋‹ค, ๋ช‡๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์žˆ๋Š”์ง€๋Š” ์•Œ๋ ค์ง€์ง€ ์•Š์Œ ๋Œ€๋žต 12๊ฐœ ์ด์ƒ ์ •๋„)

 

 

์•„์ดํฐ์€ 16๋ฐ€๋ฆฌ์˜ 1์ดˆ๋งˆ๋‹ค ๊ต‰์žฅํžˆ ๋น ๋ฅด๊ฒŒ ๋ฆฌํ”„๋ ˆ์‹ฑ์„ ํ•˜๋Š”๋ฐ

๊ทธ ์ž‘์—…์„ ๋ฌด์–ธ๊ฐ€๊ฐ€ ๋ฐฉํ•ดํ•˜๊ณ  ์žˆ์–ด์„œ ์˜์ƒ์ฒ˜๋Ÿผ ๋ฒ„๋ฒ…์ด๋Š” ํ˜„์ƒ ๋ฐœ์ƒํ•œ๋‹ค!

์•„์ดํฐ์€ ์ผํ•˜๋Š” ๋…€์„์ด ์—ฌ๋Ÿฟ์ธ๋ฐ ์™œ ๋ฒ„๋ฒ…์˜€๋Š”๊ฐ€?

๐Ÿ’ก → ํ•œ๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ์—์„œ๋งŒ ์ผ์„ ์‹œ์ผฐ๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„๋ฒ…์ธ ๊ฒƒ.

cmd + 7 ๋ˆ„๋ฅด๋ฉด ์œ„์ฒ˜๋Ÿผ ์–ด๋–ค ์Šค๋ ˆ๋“œ๊ฐ€ ์ผํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธ ๊ฐ€๋Šฅ

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ž˜๋ชปํ•ด์„œ ์šฐ์—ฐ์ฐฎ๊ฒŒ ํ™”๋ฉด์„ ๊ด€๋ฆฌํ•˜๋Š” ํ•œ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋งŒ ๊ณ„์† ์‚ฌ์šฉํ•ด์„œ ๋ฒ„๋ฒ…์ด๊ฒŒ ๋จ

๊ทธ๋™์•ˆ์—๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ž‘์€ ์ผ๋“ค๋กœ๋งŒ ์‹œ์ผœ์„œ ๋ฒ„๋ฒ…์ด๋Š” ๊ฒƒ์„ ๋ชป ๋Š๋ผ๊ณ  ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•„์š”์„ฑ์„ ๋ชป ๋Š๊ผˆ๋‹ค!

์•„๋ž˜์˜ ์ผ๋“ค์€ ์Šค๋ ˆ๋“œ๊ฐ€ ์—„์ฒญ ๋นจ๋ฆฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ผ๋“ค์ด์–ด์„œ ๋ฒ„๋ฒ…์ž„ X

print("task1: ์ถœ๋ ฅํ•˜๊ธฐ")
print("task2: ์ถœ๋ ฅํ•˜๊ธฐ")
print("task3: ์ถœ๋ ฅํ•˜๊ธฐ")
print("task4: ์ถœ๋ ฅํ•˜๊ธฐ")
print("task5: ์ถœ๋ ฅํ•˜๊ธฐ")

์œ„์—์„œ ๋ดค๋˜ ๋ฒ„๋ฒ…์ด๋Š” ํ™”๋ฉด์€ ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ์ผ์„ ์‹œ์ผฐ๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„๋ฒ…์ด๋Š” ๊ฒƒ!

(๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด

  1. ์••์ถ•ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ
  2. ์••์ถ• ํ’€๊ธฐ
  3. ์ด๋ฏธ์ง€ํŒŒ์ผ ๋ณ€ํ˜•
  4. ์…€์— ์ด๋ฏธ์ง€ ํ‘œ์‹œ

์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ์ผ๋“ค์„ ํ•˜๋Š”์ค‘์ด๋ผ ๋ถ€ํ•˜๊ฐ€ ๊ฑธ๋ฆผ ;;)

๊ทธ๋™์•ˆ ์šฐ๋ฆฌ๋Š” ..... ๋ณต์‚ฌ๊ธฐ๊ฐ€ ์—„์ฒญ ๋งŽ์€๋ฐ๋„ ํ•œ ๋ณต์‚ฌ๊ธฐ๋กœ๋งŒ ์ผ์„ํ•˜๋Š” ๋ฐ”๋ณด๊ฐ™์€ ์ง“์„ ... ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ...

๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์ด๋Ÿฌํ•œ ๋งŽ์€ ์ž‘์—…์„ ๋ถ„์‚ฐ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•!!!!!!

(๋‹ค๋ฅธ์“ฐ๋ ˆ๋“œ์—์„œ ๋™์‹œ์— ์ผํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ~!)

iOS ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ์ž‘์—…์„ “๋Œ€๊ธฐํ–‰๋ ฌ(Queue)"์— ๋ณด๋‚ด๊ธฐ๋งŒํ•˜๋ฉด OS๊ฐ€ ์•Œ์•„์„œ ์“ฐ๋ ˆ๋“œ์— ๋ถ„์‚ฐ์ฒ˜๋ฆฌ ํ•ด์ค€๋‹ค.(๊ณ ๋ง™๊ณ  ๋˜˜๋˜˜ํ•œ ๋…€์„ ...)

๊ทธ๋ฆผ์„ ๋ณด๋ฉด Queue๊ฐ€ ์•Œ์•„์„œ ์“ฐ๋ ˆ๋“œ๋ฅผ ๋ฐฐ์น˜ ํ•ด์คฌ๋‹ค. ๋จผ์ € ๋“ค์–ด์˜จ๋…€์„์ด ๋จผ์ € ๋ฐฐ์น˜๋œ๋‹ค.

ํ•˜์ง€๋งŒ!! ๋จผ์ € ๋ฐฐ์น˜๋œ๋‹ค๊ณ  ๊ทธ ์ž‘์—…์ด ๋จผ์ € ๋๋‚˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

“์šฐ๋ฆฌ๊ฐ€ ํ• ์ผ์€ ์˜ค์ง ์ž‘์—…์„ ํ(Queue)๋กœ ๋ณด๋‚ด์ž !”

2) ๊ฐ„๋‹จํ•œ GCD/Operation ์†Œ๊ฐœ

iOS ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋Œ€๊ธฐํ–‰๋ ฌ(Queue)์—๋Š” ๋‘๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค !!

  1. GCD
  2. Operation

์šฐ๋ฆฌ๋Š” ์–˜๋„คํ•œํ…Œ ์ž‘์—…์„ ๋„ฃ์–ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ์–˜๋„ค๊ฐ€ ์•Œ์•„์„œ ๋ถ„์‚ฐ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ์ผํ•จ ..

์‹œ์Šคํ…œ์ด GCD/Operation์„ ๋ณด๊ณ  ์•Œ์•„์„œ ์“ฐ๋ ˆ๋“œ ์ˆซ์ž ๊ด€๋ฆฌํ•œ๋‹ค.

(์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ์ƒ์„ฑํ•˜๋Š”๊ฑฐ๋ณด๋‹ค ์•„๋งˆ ๋” ์ž˜ํ• ๊ฒƒ..๊ฑ ์–˜๋„ค ์‹œ์ผœ๋ผ..)

GCD/Operation์€ ์“ฐ๋ ˆ๋“œ๋ณด๋‹ค ํ•œ๋‹จ๊ฒŒ ๋†’์€ ์ฐจ์›์—์„œ ์ผํ•˜๋ฉด์„œ ์ž‘์—…๋“ค์ด “๋น„๋™๊ธฐ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก” ๋งŒ๋“ค์–ด ์ค€๋‹ค~! (์–ด๋–ค API๋“ค์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋˜๋„๋ก ์„ค๊ณ„๋˜์–ด์žˆ์Œ ์™•์‹ ๊ธฐ)

๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ํ(GCD/Operation)๋กœ ๋ณด๋‚ด๋Š”๊ฐ€ !?!

๋ฐฉ๋ฒ• 1 ๋šœ๋‘”

DispatchQueue.global().async {
    
    //๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๋กœ ๋ณด๋‚ผ ์ž‘์—…์„ ๋ฐฐ์น˜
    
}

๋ฐฉ๋ฒ• 2 ๋šœ๋‘”(์„ ์–ธ ๋จผ์ €ํ•˜๋Š” ๋ฐฉ๋ฒ•)

let queue = DispatchQueue.global()

queue.async {
    
    //๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๋กœ ๋ณด๋‚ผ ์ž‘์—…์„ ๋ฐฐ์น˜
    
}

 

 

async{ task} → ์ž‘์—…์˜ ํ•œ๋‹จ์œ„์”ฉ ๋“ค์–ด๊ฐ

func secondTask0() -> String {
    return "โ˜… ์ž‘์—…1, "
}

func secondTask1(inString: String) -> String {
    return inString + "์ž‘์—…2, "
}

func secondTask2(inString: String) -> String {
    return inString + "์ž‘์—…3 โ˜…"
}

// ์ˆœ์„œ๊ฐ€ ํ•„์š”ํ•œ ์ž‘์—… ์‹คํ–‰ํ•ด๋ณด๊ธฐ
DispatchQueue.global().async {
    let out0 = secondTask0()
    let out1 = secondTask1(inString: out0)
    let out2 = secondTask2(inString: out1)
    print(out2)
}

์ถœ๋ ฅ

โ˜… ์ž‘์—…1, ์ž‘์—…2, ์ž‘์—…3 โ˜… 

ํ•˜๋‚˜์˜ async{} ๊ด„ํ˜ธ ์•ˆ์—์„œ๋Š” ์ˆœ์„œ๋Œ€๋กœ ์ฐจ๊ณก์ฐจ๊ณก ์ง„ํ–‰๋จ .

GCD (Grand Central Dispatch : ๋””์ŠคํŒจ์น˜ ํ)

  • ๊ฐ„๋‹จํ•œ ์ผ
  • ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ž‘์—…, ํด๋กœ์ ธ๋กœ ๋ฌถ์€ ์•„์ด๋“ค ์ž‘์—…

Operation(: ์˜คํผ๋ ˆ์ด์…˜ํ)

  • ๋ณต์žกํ•œ ์ผ
  • ๋ฐ์ดํ„ฐ์™€ ๊ธฐ๋Šฅ์„ ์บก์Šํ™”ํ•œ ๊ฐ์ฒด

๐Ÿ’ก Operation์€ GCD๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ธฐ๋Šฅ(์ทจ์†Œ, ์ˆœ์„œ์ง€์ •, ์ผ์‹œ์ •์ง€ ๋“ฑ)์„ ์ถ”๊ฐ€ ํ•˜์—ฌ 2016๋…„๋„์— ์• ํ”Œ์ด ๋ฐœํ‘œํ•œ ๊ฐœ๋…!!!! ๋‘˜ ์ค‘์— ๊ผญ ๋ญ˜์จ์•ผํ•˜๋Š”๊ฑฐ๋Š” ์—†๋‹ค. ํ”„๋กœ์ ํŠธ์˜ ํšจ์œจ์„ฑ, ์‚ฌ๋ก€ ์ ํ•ฉ์„ฑ์— ๋”ฐ๋ผ ์ •ํ•ด์•ผํ•œ๋“œ์•„. operation์€ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด๋ผ์„œ ํ•œ๋ฒˆ ๋งŒ๋“ค์–ด๋†“์œผ๋ฉด ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•˜๊ธด ํ•˜๋‹คํ•จ (์˜ฌ.)

 

3)Synchronous(๋™๊ธฐ)์™€ Asynchonous(๋น„๋™๊ธฐ)์˜ ์ฐจ์ด

๋น„๋™๊ธฐ async

  • ์ž‘์—…์„ 2๋ฒˆ ์“ฐ๋ ˆ๋“œ์— ๋ณด๋‚ด๊ณ ๋‚˜์„œ ์ด ์ž‘์—…์ด ๋๋‚˜๋Š”๊ฑธ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  1๋ฒˆ ์“ฐ๋ ˆ๋“œ๋กœ ๋ฐ”๋กœ ๋Œ์•„์˜ค๋Š” ๊ฒƒ (์ฆ‰์‹œ ๋ฆฌํ„ด)
  • ์ผ์„ ์‹œ์ž‘ ์‹œ์ผœ๋†“๊ณ  ๊ทธ ์ž‘์—…์ด ๋๋‚ ๋–„๊นŒ์ง€ “์•ˆ ๊ธฐ๋‹ค๋ฆฐ๋‹ค” → ๋”ฐ๋ผ์„œ ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ(1๋ฒˆ์“ฐ๋ ˆ๋“œ)๊ฐ€ ๋ฐ”๋กœ ๋‹ค๋ฅธ ์ผ์„ ์‹œ์ž‘ ํ•  ์ˆ˜ ์žˆ๋‹ค.

let queue = DispatchQueue.global()

func task1() {
    print("Task 1 ์‹œ์ž‘")
    sleep(1)
    print("Task 1 ์™„๋ฃŒโ˜…")
}

func task2() {
    print("Task 2 ์‹œ์ž‘")
    print("Task 2 ์™„๋ฃŒโ˜…")
}

func task3() {
    print("Task 3 ์‹œ์ž‘")
    sleep(4)
    print("Task 3 ์™„๋ฃŒโ˜…")
}

func task4() {
    print("Task 4 ์‹œ์ž‘")
    sleep(3)
    print("Task 4 ์™„๋ฃŒโ˜…")
}

queue.async {
    task1()
}

queue.async {
    task2()
}

queue.async {
    task3()
}

์ถœ๋ ฅ

Task 1 ์‹œ์ž‘
Task 3 ์‹œ์ž‘
Task 2 ์‹œ์ž‘
Task 2 ์™„๋ฃŒโ˜…
Task 1 ์™„๋ฃŒโ˜…
Task 3 ์™„๋ฃŒโ˜…

๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋Š” ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ฉ”์ธ์“ฐ๋ ˆ๋“œ๋กœ ๋Œ์•„์™€์„œ ๋‹ค๋ฅธ ์ž‘์—…๋“ค์„ ์‹œ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์—

์ œ๊ฐ๊ฐ ์‹œ์ž‘ํ•˜๊ณ  ์ œ๊ฐ๊ฐ ๋๋‚จ

๐Ÿ’ก ๋น„๋™๊ธฐ๋ผ๋Š” ๊ฐœ๋…์ด ์ผ๋ฐ˜์ ์œผ๋กœ ํ•„์š”ํ•œ ์ด์œ ๋Š”?

 

A : ๋Œ€๋ถ€๋ถ„์€ ์„œ๋ฒ„์™€์˜ ํ†ต์‹ (๋„คํŠธ์›Œํฌ ์ž‘์—…) ๋•Œ๋ฌธ์ด๋‹ค. (๋„คํŠธ์›Œํฌ์™€ ๊ด€๋ จ๋œ ์ž‘์—…๋“ค์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๊ตฌํ˜„ ์˜ˆ: URLSession)

4) Serial(์ง๋ ฌ) VS Concurrency(๋™์‹œ)

Serial๊ณผ Concurrency๋Š” ํ์˜ ๋‘๊ฐ€์ง€ ํŠน์„ฑ ์ข…๋ฅ˜

Serial Queue (์ง๋ ฌํ) : ๋‹จ ํ•˜๋‚˜์˜ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ๋งŒ ๋ณด๋‚ด๋Š” ํŠน์„ฑ์„ ๊ฐ€์ง„ ๋Œ€๊ธฐ์—ด. ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉ

Concurrentํ (๋™์‹œํ): ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ทธ๋Ÿฐ ํ. ๊ฐ์ž ๋…๋ฆฝ์ ์ด์ง€๋งŒ ์œ ์‚ฌํ•œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉ

(์œ„์˜ ๋ฒ„๋ฒ…์ด๋˜ ์˜ˆ์ œ๋Š” ์…€ํ•˜๋‚˜ํ•˜๋‚˜๊ฐ€ ์„œ๋ฒ„์— ์š”์ฒญํ•ด์„œ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๊ณ  ํ•„ํ„ฐ๋งํ•˜๊ณ  ๊ทธ๋Ÿฐ ์ž‘์—…๋“ค. ์…€ ํ•˜๋‚˜ํ•˜๋‚˜๊ฐ€ ๊ฐ์ž ๋…๋ฆฝ ๋˜์—ˆ์ง€๋งŒ ์œ ์‚ฌํ•œ ์ž‘์—…)

๋น„๋™๊ธฐ๋ž€ ๋ง๊ณผ ๋™์‹œ๋ž€ ๋ง์ด ๊ฐ™์€ ๋ง์ธ๊ฐ€? : ์ „ํ˜€ ๋‹ค๋ฅธ ๋ง์ด๋‹ค.

๋น„๋™๊ธฐ๋ผ๋Š” ๋ง์€ ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๋กœ ๋ถ„์‚ฐ์ฒ˜๋ฆฌ ์‹œํ‚ค๊ณ  ๊ทธ์ž‘์—…์ด ๋๋‚˜๊ธธ “๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๋Š”๊ฒƒ" .

๋™์‹œ๋ผ๋Š” ๋ง์€ ๋Œ€๊ธฐ์—ด๋กœ ๋ณด๋‚ด์ง„ ์ž‘์—…์ด “์—ฌ๋Ÿฌ๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๋กœ ๊ฐ€๋Š” ๊ฒƒ”