suspend

2024. 12. 27. 00:48·개념 저장소/coroutine

1. suspend 함수란

suspend 함수는 코루틴 내에서만 호출할 수 있는 특수한 함수이다.
이 함수는 실행 중 특정 시점에서 중단되었다가 필요할 때 다시 실행을 재개할 수 있는 특성을 가진다.

2. 특징

  1. 중단 가능: suspend 함수는 특정 조건에서 중단될 수 있으며 이후 다시 재개된다.
  2. 코루틴 컨텍스트: suspend 함수는 호출될 때 코루틴의 컨텍스트에서 실행된다.
  3. 스레드가 항상 돌아오는 것은 아님: 중단된 suspend 함수가 다시 실행될 때 같은 스레드가 아니라 다른 스레드에서 실행될 수 있다. 코루틴 디스패처의 정책에 따라 결정된다.
  4. 직관적인 비동기 코드 작성: 콜백 지옥을 피하고, 비동기 코드를 동기 코드처럼 작성할 수 있다.
suspend fun example(st: String) {
    println("작업 시작 $st - ${Thread.currentThread().name}")
    delay(1000) // 1초 동안 중단
    println("작업 재개 $st - ${Thread.currentThread().name}")
}

fun main(): Unit = runBlocking {
    launch(Dispatchers.IO) {
        example("qwer1") // 코루틴 내부에서 호출
    }
    launch(Dispatchers.IO) {
        example("qwer2") // 코루틴 내부에서 호출
    }

    launch(Dispatchers.IO) {
        example("qwer3") // 코루틴 내부에서 호출
    }

    launch(Dispatchers.IO) {
        example("qwer4") // 코루틴 내부에서 호출
    }

    launch(Dispatchers.IO) {
        example("qwer5") // 코루틴 내부에서 호출
    }
}

작업이 재개 되었을 때 같은 스레드에서 시작되지 않을 수 도 있다.

suspend fun example(st: String, time: Long) {
    delay(time) // 1초 동안 중단
    println("작업 시작 $st - ${Thread.currentThread().name}")
    delay(1000) // 1초 동안 중단
    println("작업 재개 $st - ${Thread.currentThread().name}")
}

fun main(): Unit = runBlocking {
    launch(Dispatchers.IO) {
        example("qwer1", 500) // 코루틴 내부에서 호출
    }
    launch(Dispatchers.IO) {
        example("qwer2", 0) // 코루틴 내부에서 호출
    }

    launch(Dispatchers.IO) {
        example("qwer3", 100) // 코루틴 내부에서 호출
    }

    launch(Dispatchers.IO) {
        example("qwer4", 200) // 코루틴 내부에서 호출
    }

    launch(Dispatchers.IO) {
        example("qwer5", 300) // 코루틴 내부에서 호출
    }
}

suspend함수는 스레드를 블로킹하지 않기 때문에 다른 작업에서 스레드를 활용할 수 있다.

3. 동작 원리

  1. Continuation 인터페이스: suspend 함수는 컴파일 시 Continuation<T>라는 인터페이스를 이용해 상태를 관리하도록 변환된다. 함수의 호출 상태를 저장하고 재개 시 이전 상태를 복원한다.
  2. 스택리스(stackless) 설계: 코루틴은 스택을 사용하지 않는 구조로 설계되어 있다. 쉽게 말해  suspend 함수가 내부적으로 다른 suspend 함수를 호출하더라도 호출 스택이 점점 깊어지는 방식으로 동작하지 않는대신 호출된 각 함수는 상태 머신으로 변환되어 호출 상태를 저장하고 필요할 때 재개될 수 있도록 관리한다.
suspend fun functionA() {
    println("A 시작")
    functionB()
    println("A 종료")
}

suspend fun functionB() {
    println("B 시작")
    delay(1000) // 중단 지점
    println("B 종료")
}

fun main() = runBlocking {
    functionA()
}





//변환 코드
class FunctionAContinuation : Continuation<Unit> {
    var state = 0
    override fun resumeWith(result: Result<Unit>) {
        when (state) {
            0 -> {
                println("A 시작")
                state = 1

                // 호출스택으로 쌓이지 않고 기존호출이 제거되고 상태를 저장한다.
                FunctionBContinuation().resumeWith(Result.success(Unit))
            }
            1 -> {
                println("A 종료")
            }
        }
    }
}

class FunctionBContinuation : Continuation<Unit> {
    var state = 0
    override fun resumeWith(result: Result<Unit>) {
        when (state) {
            0 -> {
                println("B 시작")
                state = 1
                delay(1000, this) // 중단
            }
            1 -> {
                println("B 종료")
            }
        }
    }
}

참고

https://www.youtube.com/watch?v=IQf-vtIC-Uc&ab_channel=AndroidDevelopers

'개념 저장소 > coroutine' 카테고리의 다른 글

Coroutine의 실행 옵션  (2) 2025.01.01
공유 자원 관리  (1) 2025.01.01
코루틴에서의 예외 처리  (0) 2024.12.22
구조화된 동시성  (2) 2024.12.21
Coroutine Context  (1) 2024.12.12
'개념 저장소/coroutine' 카테고리의 다른 글
  • Coroutine의 실행 옵션
  • 공유 자원 관리
  • 코루틴에서의 예외 처리
  • 구조화된 동시성
jamin
jamin
  • jamin
    jamin
    jamin
  • 전체
    오늘
    어제
    • 전체 (86) N
      • 트러블슈팅 (31)
      • 개념 저장소 (22) N
        • coroutine (10)
        • spring reactive (9)
        • network (3) N
      • 코딩 테스트 (32)
  • 태그

    코테
    그리디 알고리즘
    dfs
    spring boot
    reactive
    instancio
    다익스트라
    log
    대용량 데이터
    BFS
    spring reactive
    sinks
    백준
    정렬
    경로압축
    error alram
    coroutine
    누적합
    다이나믹 프로그래밍
    백준 23758
    코딩테스트
    mirroring mode
    batch
    수학
    cluster mode
    분리집합
    JPA
    Kotlin
    그리디
    DP
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
jamin
suspend
상단으로

티스토리툴바