티스토리 뷰
728x90
6. 코루틴 취소 및 타임아웃
6.1 코루틴 취소 (Cancellation)
코루틴은 비동기적으로 동작하므로, 때로는 진행 중인 작업을 중단해야 할 필요가 있습니다. 코루틴을 취소하는 것은 중요한 작업이며, 취소된 코루틴은 즉시 중단되지만 정리 작업(clean-up)을 할 수 있는 기회도 제공합니다.
코루틴의 취소는 협력적으로 이루어집니다. 이는 코루틴이 명시적으로 취소 상태를 확인하거나, 취소 가능한 함수(delay
, yield
등)를 호출할 때만 취소된다는 뜻입니다.
코루틴 취소의 기본 사용 예제
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
repeat(1000) { i ->
println("Job: I'm working on $i ...")
delay(500L) // `delay`는 취소 가능한 함수
}
}
delay(1300L) // 잠시 기다렸다가
println("Main: I'm tired of waiting!")
job.cancel() // 코루틴을 취소
job.join() // 코루틴이 완전히 종료될 때까지 기다림
println("Main: Now I can quit.")
}
설명:
launch
는 비동기 작업을 시작하고,repeat
블록 내에서 반복 작업을 수행합니다.delay
는 취소 가능한 함수로, 취소가 요청되면 코루틴이 중단됩니다.job.cancel()
로 코루틴을 취소하고,job.join()
으로 코루틴이 완료될 때까지 기다립니다.
출력:
Job: I'm working on 0 ...
Job: I'm working on 1 ...
Job: I'm working on 2 ...
Main: I'm tired of waiting!
Main: Now I can quit.
요점:
- 코루틴 취소는 협력적으로 이루어집니다. 취소 요청을 받은 후에도 코루틴이 취소 가능한 지점에서만 중단됩니다.
delay
,yield
같은 취소 가능한 함수를 호출해야 취소가 실제로 이루어집니다.
6.2 코루틴의 취소 상태 확인
코루틴 내에서 취소 상태를 확인하려면, isActive
속성을 사용합니다. isActive
는 코루틴이 취소되었는지 여부를 확인할 수 있는 협력적 플래그입니다. 코루틴이 취소되면 isActive
가 false
가 됩니다.
isActive
를 사용한 취소 상태 확인 예제
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
repeat(1000) { i ->
if (!isActive) return@launch // 취소 상태 확인
println("Job: I'm working on $i ...")
delay(500L)
}
}
delay(1300L)
println("Main: I'm tired of waiting!")
job.cancel()
println("Main: Now I can quit.")
}
설명:
isActive
는 코루틴의 취소 상태를 확인하는 데 사용됩니다.- 코루틴이 취소되면
isActive
가false
가 되어, 더 이상 작업을 진행하지 않고 즉시 중단됩니다.
출력:
Job: I'm working on 0 ...
Job: I'm working on 1 ...
Job: I'm working on 2 ...
Main: I'm tired of waiting!
Main: Now I can quit.
요점:
isActive
는 코루틴이 취소되었는지 여부를 확인하는데 사용되며, 이를 통해 중단 가능한 작업을 제어할 수 있습니다.
6.3 코루틴의 정리 작업 (Clean-up)
코루틴이 취소될 때, 특정한 정리 작업을 수행해야 할 때가 있습니다. 이를 위해 try-finally
블록을 사용할 수 있습니다. finally
블록은 코루틴이 취소되더라도 항상 실행됩니다.
코루틴 취소 시 정리 작업 예제
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
try {
repeat(1000) { i ->
println("Job: I'm working on $i ...")
delay(500L)
}
} finally {
println("Job: I'm running finally block to clean up resources.")
}
}
delay(1300L)
println("Main: I'm tired of waiting!")
job.cancelAndJoin() // 코루틴을 취소하고 종료될 때까지 기다림
println("Main: Now I can quit.")
}
설명:
try-finally
를 사용하여 취소된 후에도 정리 작업을 수행할 수 있습니다.finally
블록은 코루틴이 취소되더라도 항상 실행되므로, 리소스를 정리하거나 파일을 닫는 작업을 처리하는 데 유용합니다.
출력:
Job: I'm working on 0 ...
Job: I'm working on 1 ...
Job: I'm working on 2 ...
Main: I'm tired of waiting!
Job: I'm running finally block to clean up resources.
Main: Now I can quit.
요점:
try-finally
를 통해 취소된 후에도 정리 작업을 안전하게 처리할 수 있습니다.cancelAndJoin()
은 코루틴을 취소하고, 완전히 종료될 때까지 기다립니다.
6.4 코루틴 타임아웃 (Timeout)
때로는 코루틴이 특정 시간 내에 완료되지 않으면 자동으로 취소되어야 하는 상황이 있습니다. 이를 위해 withTimeout
함수를 사용할 수 있습니다. withTimeout
은 주어진 시간이 지나면 TimeoutCancellationException을 던지며, 코루틴을 취소합니다.
withTimeout
사용 예제
import kotlinx.coroutines.*
fun main() = runBlocking {
try {
withTimeout(1300L) { // 1.3초 후에 타임아웃 발생
repeat(1000) { i ->
println("I'm working on $i ...")
delay(500L) // 0.5초 지연
}
}
} catch (e: TimeoutCancellationException) {
println("Timed out!")
}
}
설명:
withTimeout
을 사용하면 지정한 시간이 지나면 코루틴이 취소됩니다.- 타임아웃이 발생하면 TimeoutCancellationException이 발생하며, 이를
try-catch
로 처리할 수 있습니다.
출력:
I'm working on 0 ...
I'm working on 1 ...
I'm working on 2 ...
Timed out!
요점:
withTimeout
을 통해 지정된 시간 내에 완료되지 않는 작업을 자동으로 취소할 수 있습니다.- 타임아웃 발생 시
TimeoutCancellationException
을 처리하여 정리 작업을 수행하거나 오류를 처리할 수 있습니다.
6.5 withTimeoutOrNull
: 타임아웃 시 null 반환
때로는 타임아웃이 발생해도 예외를 발생시키지 않고, 대신 null을 반환하게 하고 싶을 수 있습니다. 이럴 때는 withTimeoutOrNull
을 사용하면 됩니다.
withTimeoutOrNull
사용 예제
import kotlinx.coroutines.*
fun main() = runBlocking {
val result = withTimeoutOrNull(1300L) { // 1.3초 후에 타임아웃 발생
repeat(1000) { i ->
println("I'm working on $i ...")
delay(500L) // 0.5초 지연
}
"Completed" // 작업이 완료되면 이 값을 반환
}
if (result == null) {
println("Timed out!")
} else {
println("Result: $result")
}
}
설명:
withTimeoutOrNull
은 타임아웃이 발생하면 null을 반환하고, 작업이 정상적으로 완료되면 결과 값을 반환합니다.- 이를 통해 타임아웃이 발생했는지 여부를 쉽게 확인할 수 있습니다.
출력:
I'm working on 0 ...
I'm working on 1
...
I'm working on 2 ...
Timed out!
요점:
withTimeoutOrNull
은 타임아웃 시 예외를 발생시키지 않고, null을 반환하여 더 유연하게 처리할 수 있습니다.
요약
- 코루틴 취소는 협력적으로 이루어지며, 취소 상태를 확인하는
isActive
또는 취소 가능한 함수(delay
,yield
)를 통해 이루어집니다. try-finally
를 통해 코루틴 취소 시에도 정리 작업을 수행할 수 있습니다.- 타임아웃은
withTimeout
을 사용하여 특정 시간 내에 완료되지 않는 작업을 자동으로 취소할 수 있습니다. withTimeoutOrNull
은 타임아웃 시 null을 반환하여 유연하게 타임아웃을 처리할 수 있습니다.
728x90
'개발 언어 > 코틀린' 카테고리의 다른 글
kotlin - coroutine (부록1) launch VS coroutineScope (0) | 2024.09.05 |
---|---|
kotlin - coroutine (7) 실제 프로젝트 적용 예제 (2) | 2024.09.05 |
kotlin - coroutine (5) 코루틴 채널(Channels) 및 흐름(Flow) (2) | 2024.09.05 |
kotlin - coroutine (4) 비동기 흐름 제어: `suspend` 함수와 `withContext` (1) | 2024.09.05 |
kotlin - coroutine (3) 코루틴의 동작 원리 및 구조화된 동시성 (Structured Concurrency) (0) | 2024.09.05 |
댓글