Skip to content

Latest commit

ย 

History

History
138 lines (102 loc) ยท 6.39 KB

coroutine.md

File metadata and controls

138 lines (102 loc) ยท 6.39 KB

Coroutine

์ž‘์„ฑ์ž : ๋ฐ•์žฌ์šฉ

๋ณธ ์ž๋ฃŒ๋Š” ์ž‘์„ฑ์ž์ธ '๋ฐ•์žฌ์šฉ'์˜ ํŒ€ Repository์˜ ๊ธ€๊ณผ ์œ ๋‹ˆํ‹ฐ ๊ต๊ณผ์„œ ์ฑ…์„ ์žฌ๊ตฌ์„ฑํ•˜์—ฌ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์–ธ์–ด(javascript, C++, Kotlin, C#)์—์„œ ์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์˜ˆ์ œ๋Š” C#์— ๊ตญํ•œ๋œ ์„ค๋ช…์œผ๋กœ ์ฝ”๋ฃจํ‹ด์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋„์™€์ค๋‹ˆ๋‹ค.

Table of Contents

Coroutine์ด๋ž€?

์ฝ”๋ฃจํ‹ด(Coroutine)์€ Cooperative routine์„ ์˜๋ฏธํ•˜๋ฉฐ ์„œ๋กœ ํ˜‘๋ ฅํ•˜๋Š” ๋ฃจํ‹ด์ด๋ผ๋Š” ๋œป์ด๋‹ค. ๋ฉ”์ธ ๋ฃจํ‹ด๊ณผ ์„œ๋ธŒ ๋ฃจํ‹ด์ฒ˜๋Ÿผ ์ข…์†๋œ ๊ด€๊ณ„๊ฐ€ ์•„๋‹Œ ์„œ๋กœ ๋Œ€๋“ฑํ•œ ๊ด€๊ณ„์ด๋‹ค. ๊ธ€์„ ์ „๋ถ€ ์ •๋…ํ•œ ํ›„ ๋‹ค์‹œ ์˜ฌ๋ผ์™”์„ ๋•Œ๋Š” ์ถฉ๋ถ„ํžˆ ์ดํ•ด๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

image

Coroutine์ด ์–ธ์ œ ์“ฐ์ด๋Š”๋ฐ?

์ง์ ‘ ๋ˆ„๊ตฌ๋‚˜ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋กœ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ๋‹ค.
์˜ˆ์‹œ1)

void start(){
    startA();
    startB();
}
void startA(){
    for(int a=0;a<10;a++){
        Debug.Log("a");
    }
}
void startB(){
    for(int b=0;b<5;b++){
        Debug.Log("b");
    }
}

ํ”„๋กœ๊ทธ๋žจ์€ startA์˜ a๊ฐ€ ์—ด๋ฒˆ, startB์˜ b๊ฐ€ ๋‹ค์„ฏ๋ฒˆ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

์œ„์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๋™์‹œ์— ์ผ์–ด๋‚˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๊ฑฐ๋‚˜ ์•ฝ์†๋œ ์‹ ํ˜ธ๋ฅผ ์คฌ์„ ๋•Œ ์‹œ์ž‘ํ•˜๋Š” ๋น„๋™๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•œ๋‹ค.

์˜ˆ์‹œ2)
์ฝ”๋ฃจํ‹ด์˜ ๊ณต์‹๋ฌธ์„œ์—์„œ๋Š” ํ•œ ์˜ค๋ธŒ์ ํŠธ์˜ ํˆฌ๋ช…๋„๋ฅผ ์™„์ „ํžˆ ํˆฌ๋ช…ํ•ด์งˆ ๋•Œ๊นŒ์ง€ Fadeout์‹œํ‚ฌ ๋•Œ ์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ์ค‘๊ฐ„๊ฐ’์€ ์‹œ๊ฐ์ ์œผ๋กœ ์•Œ ์ˆ˜ ์—†๊ณ  ์ˆœ๊ฐ„์ ์œผ๋กœ ํˆฌ๋ช…ํ•ด์ง€๋ฏ€๋กœ ์ฝ”๋ฃจํ‹ด์„ ์ด์šฉํ•˜์—ฌ ํˆฌ๋ช…๋„๋ฅผ ์„ค์ •ํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ˆœ์‹๊ฐ„์— ํˆฌ๋ช…๋„๊ฐ€ 0์œผ๋กœ ๋ณ€ํ•ด๋ฒ„๋ฆฐ๋‹ค.

void Fade() {
    for (float f = 1f; f >= 0; f -= 0.1f) {
        Color c = renderer.material.color;
        c.a = f;
        renderer.material.color = c;
    }
}

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ฝ”๋ฃจํ‹ด์„ ์ ์šฉ์‹œํ‚จ ์ฝ”๋“œ์ด๋‹ค. ์ •ํ•ด์ง„ ์‹œ๊ฐ„์ด๋‚˜ ํ”„๋ ˆ์ž„๋งˆ๋‹ค ํˆฌ๋ช…๋„๋ฅผ ์„œ์„œํžˆ ์ค„๊ฒŒ ์ž์‹ ์ด ์†๋„๋ฅผ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

IEnumerator Fade() {
    for (float f = 1f; f >= 0; f -= 0.1f) {
        Color c = renderer.material.color;
        c.a = f;
        renderer.material.color = c;
        yield return null;
    }
}

์ฝ”๋ฃจํ‹ด์ด ์ฃผ๋Š” ์ด์ 

๊ฒฐ๋ก ๋งŒ ๋งํ•˜์ž๋ฉด ์ฝ”๋ฃจํ‹ด์„ ํ˜‘๋ ฅํ˜• ๋ฉ€ํ‹ฐํƒœ์Šคํ‚น(cooperative multitasking)์„ ๊ตฌํ˜„ํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋ฃจํ‹ด์ด ์ฃผ๋Š” ์ด์ ์ด ๋งŽ๋‹ค๊ณ  ์ด์•ผ๊ธฐ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ˜‘๋ ฅํ˜• ๋ฉ€ํ‹ฐํƒœ์Šคํ‚น์€ ์ผ์ข…์˜ ์‹œ๋ถ„ํ•  - time sharing ๋ฐฉ์‹์œผ๋กœ ์—ฌ๋Ÿฌ task๊ฐ€ ํ•˜๋‚˜์˜ CPU๋ฅผ ๋‚˜๋ˆ ์“ฐ๋Š” ๋ฐฉ์‹์ธ๋ฐ ์šด์˜์ฒด์ œ์˜ ๊ฐœ์ž… ์—†์ด ๊ฐ task๊ฐ€ ๋…์ ์ ์œผ๋กœ CPU๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‚ฌ์šฉ์ด ๋๋‚˜๋ฉด ์ž๋ฐœ์ ์œผ๋กœ ์–‘๋ณดํ•˜๊ฒŒ ๋œ๋‹ค. ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋„์ค‘ ๊ฐ•์ œ๋กœ CPU๋ฅผ ์„ ์ ํ•ด๊ฐ€๋Š” ์ผ์ด ์—†์œผ๋ฏ€๋กœ ํฌ๋ฆฌํ‹ฐ์ปฌ ์„น์…˜์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•œ ๋™๊ธฐํ™” ์ˆ˜๋‹จ์ด ํ•„์š” ์—†๋‹ค๋Š”๊ฒƒ์ด ๊ฐ€์žฅ ํฐ ์ด์ ์ด๋‹ค.


์ฝ”๋ฃจํ‹ด๊ณผ ์ผ๋ฐ˜ํ•จ์ˆ˜์˜ ์ฐจ์ด์ 

์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜์˜ ์ง„์ž…์ ์€ ํ•จ์ˆ˜์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์ด๋‹ค. ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ํ•จ์ˆ˜์˜ ์‹œ์ž‘ ๋ถ€๋ถ„๋ถ€ํ„ฐ return์ด๋‚˜ ํ•จ์ˆ˜์˜ ๋๊นŒ์ง€ ์‹คํ–‰์„ ํ•œ ํ›„ ํ•จ์ˆ˜๋ฅผ ์ข…๋ฃŒํ•œ๋‹ค. Coroutine์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ง„์ž…์ ๊ณผ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ค‘๋‹จ์ ์„ ๊ฐ€์ ธ ๋ฃจํ‹ด์ด ์ข…๋ฃŒ๋˜๊ธฐ ์ „์— ๋ช‡๋ฒˆ์ด๋“  ์ง„์ž…๊ณผ ์ค‘๋‹จ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๋˜ํ•œ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด ํ•จ์ˆ˜๋Š” return์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์ฝ”๋ฃจํ‹ด์€ suspend(์ค‘๋‹จ)์„ ์‚ฌ์šฉํ•˜์—ฌ ํž™ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์— ๋‹ค์‹œ resume(์žฌ๊ฐœ)ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ณ  ์ œ์–ด๊ถŒ์„ ํ˜ธ์ถœ์ž์—๊ฒŒ ๋‹ค์‹œ ๋„˜๊ธฐ๊ฒŒ ๋œ๋‹ค.

์ฝ”๋ฃจํ‹ด๊ณผ ์Šค๋ ˆ๋“œ์˜ ์ฐจ์ด์ 

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

image

Coroutine์˜ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

StartCoroutine(ํ•จ์ˆ˜์ด๋ฆ„())์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ์— StartCoroutine์„ ์•„๋ž˜์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

C#

void start(){
    StartCoroutine(startA());
    StartCoroutine(startB());
}
IEnumerator startA(){
    for(int a=0;a<10;a++){
        Debug.Log("a");
        yield return null;
    }
}
IEnumerator startB(){
    for(int b=0;b<5;b++){
        Debug.Log("b");
        yield return null;
    }
}

IEnumerator๋ž€?

๋ฐ์ดํ„ฐ์˜ ๋ชฉ๋ก์„ ํ•˜๋‚˜์”ฉ ๋„˜๊ฒจ์ค„ ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋กœ, ์ฝ”๋ฃจํ‹ด์€ ํ˜ธ์ถœํ•œ ํ•จ์ˆ˜์™€ ์„œ๋กœ ์ƒํ˜ธ์ž‘์šฉํ•˜๋ฉฐ ์ง„ํ–‰ํ•˜๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ๋‹ค. ํ˜ธ์ถœํ•œ ํ•จ์ˆ˜์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ์ฃผ๊ณ  ์‰ฐ ํ›„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์•ผ ํ•  ๋•Œ ์‰ฌ๊ณ  ์žˆ๋˜ ์ฝ”๋ฃจํ‹ด์ด ์ผ์–ด๋‚˜์„œ ๋‹ค์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ณ , ๋„˜๊ฒจ์ฃผ๋Š” ๋ฐ˜๋ณตํ•˜๋Š” ๊ตฌ์กฐ๋กœ ๋™์ž‘ํ•˜๊ฒŒ ๋œ๋‹ค.

yield๋ž€?

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋งˆ๋‹ค ํ•ด์„์˜ ์ฐจ์ด์ ์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ C#์˜ yield ํ‚ค์›Œ๋“œ๋Š” ํ˜ธ์ถœ์ž(Caller)์—๊ฒŒ ์ปฌ๋ ‰์…˜ ๋ฐ์ดํƒ€๋ฅผ ํ•˜๋‚˜์”ฉ ๋ฆฌํ„ดํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ํ”ํžˆ Enumerator(Iterator)๋ผ๊ณ  ๋ถˆ๋ฆฌ์šฐ๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์€ ์ง‘ํ•ฉ์ ์ธ ๋ฐ์ดํ„ฐ์…‹์œผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํƒ€๋ฅผ ํ•˜๋‚˜์”ฉ ํ˜ธ์ถœ์ž์—๊ฒŒ ๋ณด๋‚ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. C++์˜ iterator(๋ฐ˜๋ณต์ž)์™€ ๊ฐ™์€ ๊ฐœ๋…์ด๋‹ค.

๋‹ค์–‘ํ•œ yield return type

  • yield return null

๋‹ค์Œ ํ”„๋ ˆ์ž„๊นŒ์ง€ ๋Œ€๊ธฐ

  • yield return new WaitForSeconds(time)

time์ดˆ ๋งŒํผ ๋Œ€๊ธฐ

  • yield return new WaitForFixedUpdate()

๋‹ค์Œ FixedUpdate๊นŒ์ง€ ๋Œ€๊ธฐ

  • yield return StartCoroutine(string name)

๋‹ค๋ฅธ ์ฝ”๋ฃจํ‹ด์ด ์ค‘๋‹จ๋ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ