해결된 질문
작성
·
50
1
안녕하세요.
먼저 선생님 강의가 도움 많이 되고 있습니다.
감사합니다.
질문이 두 가지 있습니다.
질문 1.
fun main() = runBlocking {
println("START")
launch {
println("1")
}
launch {
println("2")
}
launch {
println("3")
}
launch {
println("4")
}
yield()
println("END")
}
이런식으로 되어 있다면
yield실행 후에 1~4번 중 어떤게 출력될지는 랜덤인건가요?
실제 실행 시에는 순서대로 되는걸 확인 했는데, 이게 항상 launch가 호출된 순서대로 출력되는건가요?
질문 2.
fun main() = runBlocking {
println("START")
launch {
println("1")
}
launch {
println("2")
}
launch {
yield()
println("3")
}
launch {
println("4")
}
yield()
println("END")
}
만약 3번에 yield 가 있다면, 어떻게 되는건가요?
3번에 들어온 순간 끝나지 않은 Coroutine 중에서 랜덤하게 호출되는건가요?
아니면 main으로 가서 END가 출력되는건가요?
감사합니다.
답변 2
1
안녕하세요! HANA님! 🙂 좋은 질문 감사드립니다.
결론부터 말씀드리면
Dispatcher
라는 친구가 코루틴을 실제 스레드에 분배하는 역할을 하기에, Dispatcher
세부 구현에 따라 다를 것 같습니다.
다만 여러 작업을 특정한 pool (이번 경우만 한정해 보면 main thread 하나가 들어 있는 pool 이 됩니다) 에 분배하려 할 때 진작 pool이 모두 가득 차 있다면, 그 앞에 BlockingQueue를 두고, pool이 비었을 때 먼저 들어왔던 작업부터 분배하는 방식이 가장 일반적이므로 "실제 실행 시에는 순서대로 되는걸 확인 했는데" 와 같이 결과가 나온 것 같습니다!
질문에 대한 답변도 드려보자면
yield실행 후에 1~4번 중 어떤게 출력될지는 랜덤인건가요?
실제 실행 시에는 순서대로 되는걸 확인 했는데, 이게 항상 launch가 호출된 순서대로 출력되는건가요?
Dispatcher
구현에 따라 다르며 제 생각에 가장 기본 구현은 호출된 순서대로 출력되게 하는것 같아요! 🙂
만약 3번에 yield 가 있다면, 어떻게 되는건가요?
3번에 들어온 순간 끝나지 않은 Coroutine 중에서 랜덤하게 호출되는건가요?
아니면 main으로 가서 END가 출력되는건가요?
무척 재밌는 생각인데요! 제 생각에는 우선은 4번을 실행할 것 같아요! 아마 아래와 같은 흐름이 아닐까~ 싶습니다! ☺
1 등록 -> 2등록 -> 3등록 -> 4등록 -> main 안의 yield() -> 등록되어 있던 1, 2, 3을 차례로 실행하다가 3 안에서 출력 전 다시 yield() -> 다음 차례는 4 -> 그 다음 다시 main -> main 자체도 runBlocking으로 만들어진 코루틴이므로 structured concurrency에 의해 자식 코루틴을 기다림 -> 3 마저 실행 -> 종료
이런 흐름이 아닐까 싶습니다!
재밌고 좋은 질문 감사드립니다 🙇
0
안녕하세요, 인프런 AI 인턴입니다. HAHA님.
코루틴 실행 순서에 대한 질문을 주셨군요. 비슷한 주제에 대한 답변들을 모아보았으니, 아래를 참고해 주세요.
질문 1. yield() 후 코루틴 실행 순서
비슷한 질문을 다루고 있는 답변을 참고해 주세요:
- 코루틴 취소 관련 질문
- Job 질문이 있습니다
질문 2. launch내의 yield 사용
이 질문은 코루틴의 협력적 취소와 제어권 전환에 관련된 내용으로 볼 수 있습니다. 비슷한 질문과 답변을 확인해 보세요:
- delay 함수에 대해 질문이 있습니다
- 코루틴의 대한 질문이 있습니다.
기본적으로 launch
는 비동기적으로 실행되기 때문에, 동일한 우선순위를 가진다면 순서는 다소 변동 가능성이 있지만, 작성하신 코드에서는 대부분의 경우 작성된 순서대로 실행될 확률이 높습니다.
하지만 코루틴 실행 순서는 결국 OS 스케줄러와 코루틴 디스패처의 스케줄링에 따라 결정되므로 절대적으로 순서를 보장할 수는 없습니다.
yield()
를 사용하게 되면 해당 코루틴은 실행 중단을 선언하고 다른 코루틴에게 실행을 양보하게 됩니다. 이 양보가 어떤 코루틴에 의해 받아들여질지는 코루틴 디스패처에 의해 결정되며, 여러 개의 작업이 대기 중이라면 랜덤하게 선택될 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
자세히 답변해주셔서 정말 감사합니다!
선생님 덕분에 궁금했던 부분이 해결됐습니다.
Dispatcher
라는 친구에 구현에 따라 다르겠지만, 선생님이 이해를 위해 설명해주신코루틴을 큐에 쌓아 놓고 순서대로 실행할 수 있다.
라는 개념을 듣고 나니 뭔가 이해가 확 됐습니다.
코루틴이 비동기적으로 실행된다고, 완전하게 랜덤하게 출력되나? 라고 생각한 것 같습니다..
답변해주셔서 정말 감사합니다!