[Kotlin] Coroutine vs. thread (Light-weight thread 가 뭔 말이야?) |
https://stackoverflow.com/questions/43021816/difference-between-thread-and-coroutine-in-kotlin
-
Coroutine 은 stackless, stackful 이렇게 두 가지 type 이 있다.
Kotlin 은 stackless coroutine 이다. stackless 이기 떄문에 약간의 기능제한이 있다.
-
Stackless coroutine 은 caller 에게 항상 무엇인가를 return 한다.
result 또는 “no result yet, I’m suspended”. 둘 중 하나이다.
Caller 는 이 2가지 형태의 return 에 대해서 대처를 해야 한다.
Caller 자체도 stackless coroutine 이라면 바로 또 다시 그의 caller 에게 값을 전달한다.
stackless coroutine 은 “resumable functions” 라고 불린다.
Stackful coroutine 은 완벽하게 일반적인 function 과 같다.
stack(caller 의 local variable 등) 과 함께 스스로 suspend 할 수도 있고, 값을 return 할 수도 있다. 일반적인 thread 같이 말이다.
그리고 scheduler 에게 다른 suspended stackful coroutine 을 수행하게 할 수 있다.
stackful coroutine 은 “cooperative multitasking” 이라고 불린다.
정리하면
stackless coroutine 은 control 을 위로(caller 에게) 보내고,
stackfull coroutine 은 control 을 아래로 보낸다고 보면 된다.
-
Stackless : C#, Scala, Kotlin
Stackful : Quasar, Javaflow
-
light-weight thread 라는 의미는..
coroutine 이 자신만의 stack 을 갖지 않는다는 의미이다.
native thread 와 mapping 이 되는 것이 아니며, context switching 등이 일어나지 않는다.
-
Thread 는 OS 에 의해 관리되며, preemptively(선매하여, 우선적으로) multitasking 이다.
Coroutine 은 User 에 의해 관리되며, cooperatively(협력하여, 협조적으로) multitasking 이다.
-
for(i in 0..10_0000){
async(CommonPool){
delay(1)
println(i)
}
}
위 코드는 2 * 10_0000 Continuation instance 를 만든다.
val job = async(CommonPool){
for(i in 0..10_0000){
delay(1)
println(i)
}
}
job.join()
이 경우 10_0001 개의 Continuation 을 만든다.
-
https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md
Coroutine
suspendable computation instance
thread 와 비슷하다. code 를 가지고 있고 수행되며 life cycle 이 있다.
그러나 실제 특정 thread 에 bound 되지 않는다.
한 thread 에서 실행되었다가 suspend 되고, 다른 thread 에서 resume 될 수 있다.
Future 와 같이 result 를 return 하면서 혹은 exception 을 던지면서 complete 될 수 있다
Suspending function
suspend 로 마킹되어 있는 녀석.
다른 suspend function 을 호출하면서 현재 thread 를 blocking 하지 않으면서 실행을 suspend 시킬 수 있다.
suspending function 은 일반 code 에서 호출할 수 없다. 오직 다른 suspending function 또는 suspending lambda 에서 호출할 수 있다.
Suspending lambda
coroutine 에서 수행되어야 하는 code block.
일반적인 lambda 와 비슷하지만, functional type 은 suspend modifier 를 가지고 있다.
anonymous suspending function 의 short syntactic form 이다.
launch, future, buildSequence 등에 suspending lambda 를 쓸 수 있다.
Suspending function type
일반적인 function type 과 같지만 suspend modifier 가 있다.
suspend () -> Int 가 그 예이다.
suspend fun foo() : Int 도 그 예이다.
Coroutine builder
suspending lambda 를 argument 로 받아서 coroutine 을 만드는 function.
launch, future, buildSequence 등이 그 예이다.
Suspension point
Coroutine 실행 중에 suspend 되는 point 를 이야기한다.
보통 suspending function 을 호출하는 지점이다.
Continuation
suspension point 에서의 coroutine state 를 이야기한다.
buildSequence{
for(i in 1..10) yield(i * i)
println(“over”)
}
여기에서 yield() 를 호출할 때마다 coroutine 은 suspend 된다.
나머지 수행이 continuation 이라 불린다.
여기에서는 10개의 continuation 을 갖는다.
coroutine 이 생성되었지만 start 되지 않은것이 initial continuation 이라 불리며 Continuation<Unit> type 이다.
-
https://stackoverflow.com/questions/1934715/difference-between-a-coroutine-and-a-thread
thread 는 stack 을 가지며 보통 1MB 사이즈를 갖는다.
64k 가 JVM 에서 thread 에 할당하는 최소 사이즈이다.
stack 을 가지고 있어 context-switching 에 cost 더 더 든다.
-
Mac OS 의 경우 process 당 2000 thread 까지 생성 가능하다.
Linux 는 thread 당 8MB stack 을 주고, 물리적 RAM 이 감당하는 수준까지 thread 를 만들 수 있다.
-
Coroutine 은 concurrent 하게 수행되지만 절대 parallel 로 실행되지 않는다.
coroutine 은 overhead(context-switching, scheduling) 가 없는 concurrency 를 제공한다.
-
Coroutine 은 언제 switch 가 되어야하는지 “반드시” 명시해주어야 한다.
반면에 thread 는 OS 가 알아서 switch 시점을 잡아 수행한다.
-
Concurrent : 두개 이상의 계산이 한 time frame 에 동시에 “존재"하고, 둘 사이에 dependency 가 있다. 실제 수행은 one by one 이다.
Parallel : 2개 이상의 계산이 "동시에" 이루어진다.
'프로그래밍 놀이터 > Kotlin, Coroutine' 카테고리의 다른 글
[도서 정리] Android Development with Kotlin - Laying a Foundation (0) | 2018.12.11 |
---|---|
[도서 정리] Android Development with Kotlin - Say hello to Kotlin (0) | 2018.12.10 |
[Kotlin] Coroutines tutorial - async code 쉽게 짜기 (17) | 2018.11.25 |
[Kotlin] private constants (0) | 2018.10.07 |
[Kotlin] findViewById shows "type inference failed..." (0) | 2018.10.06 |
댓글