인프런 커뮤니티 질문&답변

김영빈님의 프로필 이미지

작성한 질문수

코틀린 코루틴 완전 정복

섹션 요약

코루틴이 멀티스레드의 단점을 해결했다는 부분에 대해 질문드립니다.

작성

·

22

·

수정됨

2

안녕하세요? 강의 잘 듣고 있습니다.

 

코루틴이 멀티스레드의 단점을 해결했다고 말씀해주셨는데요, 관련해서 약간 정리가 되는 듯 안되는듯 하여 질문드립니다.

1. 우선 아래의 정리가 맞는지 여쭤보고 싶습니다.

  • 멀티 스레딩의 문제점은 결국 blocking이고 이 blocking을 해결하기 위해 코루틴을 도입했음

  • 코루틴은 스레드를 점유하는 형태로 동작하므로, 반대로 코루틴이 blocking될때 스레드를 점유하지 않음으로써 다른 코루틴이 해당 스레드를 점유하게 되고 결과적으로 스레드가 blocking되는 일이 없어진다.

 

2. 그런데 blocking이 되는 현상이 언제발생하나요?

  • 강의에서 말씀해주신 내용에 따르면, 다른 스레드 혹은 코루틴의 결과가 필요할 때 blocking되는 상황에 놓여지는 것 같은데 맞을까요?

  • 결국 그렇다고하면 이전 코드의 완료를 보장하는, 그러니까 sync한 방식으로 코딩을 해야할 때 스레드가 놀지 않으면서 & completableFuture처럼 콜백지옥이나 예외처리가 어렵지 않게 하는 것이 코루틴의 장점이 맞을까요?

 

3. 일반적인 IO상황도 위에서 얘기한 blocking이 맞을까요?

  • 다르게 말하면, Dispatcher IO에서 [요청을 보내고 기다려야만 하는 상황]에서도 코루틴은 스레드의 점유권을 내려놓음으로써 해당 스레드가 다른 작업을 처리할 수 있게 되는걸까요?

  • 예를 들면, A스레드가 코루틴의 DIspatcher IO에 의해 관리되는 IO전용 스레드고 IO스레드는 해당스레드하나만 존재할때(가용가능한 다른 스레드가 없는 상황)

    • c코루틴은 서버에 호출을 보내서 4초가 걸리고, d코루틴은 서버에 호출을 보내서 5초가 걸리면 A스레드에서 c코루틴과 d코루틴을 병렬적으로 처리할 수 있는건가요?

    • 단순히 다른 스레드를 하나 생성해서 두가지 작업을 다 맡겼더라면 해당 스레드에서 4초 + 5초해서 9초가 걸렸을텐데, 코루틴기반의 A스레드에서는 약 5초정도밖에(조금 더 길수는 있겠지만) 안걸리는 게 맞을까요?

 

 4. 3번에 이어지는 질문인데요, 만약 3번이 맞다고 하면 IO작업의 응답이 왔을 때 콜백같은 게 적용이 되어서 Dispatcher에 새로운 작업으로 추가되는걸까요?

  • 그러면, IO요청을 보낸 스레드와 IO응답을 처리하게 되는 스레드가 왠지 다를 수도 있을 것 같은데 맞을까요?

 

3번이 맞다고 하면, 코루틴은 아주 아름다운 것일 것 같은데 굉장히 설레네요 ㅎㅎ

좋은 강의 감사합니다.

 


답변 1

2

조세영님의 프로필 이미지
조세영
지식공유자

1. 우선 아래의 정리가 맞는지 여쭤보고 싶습니다.
코루틴은 스레드를 점유하는 형태로 동작하므로, 반대로 코루틴이 blocking될때 스레드를 점유하지 않음으로써 다른 코루틴이 해당 스레드를 점유하게 되고 결과적으로 스레드가 blocking되는 일이 없어진다.

답변: 코루틴은 스레드를 사용하지 않을 때 blocking 될 수도 있지만, 일반적으로 스레드를 사용하지 않을 때는 양보하는 방식으로 동작합니다. 이와 관련된 부분은 강의 섹션 11. 코루틴의 이해 에서 조금 더 자세한 설명을 확인하실 수 있습니다.



2. 그런데 blocking이 되는 현상이 언제발생하나요?

강의에서 말씀해주신 내용에 따르면, 다른 스레드 혹은 코루틴의 결과가 필요할 때 blocking되는 상황에 놓여지는 것 같은데 맞을까요?

답변: blocking이라기 보다는 "스레드를 양보하고 결과가 올 때까지 대기하는 상황에 놓여진다"라고 표현하는 것이 좋을 것 같습니다. blocking은 일반적으로 스레드를 사용하지 못하게 만들 때 사용하는 경우가 많아서요.

결국 그렇다고하면 이전 코드의 완료를 보장하는, 그러니까 sync한 방식으로 코딩을 해야할 때 스레드가 놀지 않으면서 & completableFuture처럼 콜백지옥이나 예외처리가 어렵지 않게 하는 것이 코루틴의 장점이 맞을까요?

답변: 넵 비동기 코드를 동기 코드 처럼 작성할 수 있는 것도 코루틴의 장점 중 하나입니다.

 

 

3. 일반적인 IO상황도 위에서 얘기한 blocking이 맞을까요?

다르게 말하면, Dispatcher IO에서 [요청을 보내고 기다려야만 하는 상황]에서도 코루틴은 스레드의 점유권을 내려놓음으로써 해당 스레드가 다른 작업을 처리할 수 있게 되는걸까요?

예를 들면, A스레드가 코루틴의 DIspatcher IO에 의해 관리되는 IO전용 스레드고 IO스레드는 해당스레드하나만 존재할때(가용가능한 다른 스레드가 없는 상황)

c코루틴은 서버에 호출을 보내서 4초가 걸리고, d코루틴은 서버에 호출을 보내서 5초가 걸리면 A스레드에서 c코루틴과 d코루틴을 병렬적으로 처리할 수 있는건가요?

답변: 병렬성은 일반적으로 여러 스레드에서 동시에 작업이 처리되는 경우를 뜻하기 때문에 이런 경우는 스레드가 하나이기 때문에 병렬적으로 처리한다고 하기보다. 비동기적으로 처리한다고 표현하는 것이 맞을 것 같습니다. 일반적인 IO 를 처리할 때 코루틴은 스레드를 양보하는 방식으로 비동기적으로 처리하기 때문에 blocking이 일어나지 않습니다.

 

단순히 다른 스레드를 하나 생성해서 두가지 작업을 다 맡겼더라면 해당 스레드에서 4초 + 5초해서 9초가 걸렸을텐데, 코루틴기반의 A스레드에서는 약 5초정도밖에(조금 더 길수는 있겠지만) 안걸리는 게 맞을까요?

답변: 일반적인 작업(루틴)은 해당 작업이 끝날 때까지 스레드를 점유(스레드 블로킹) 하는 방식으로 동작하기 때문에 9초가 걸리는 것이 맞습니다. 하지만, 작업을 코루틴으로 만들면 스레드를 사용하지 않을 때는 양보하기 때문에 5초가 걸릴 수도 있습니다.
더욱 자세히 말씀드리면 이 경우는 상황이 두가지로 나뉠 수 있는데요. 만약 각 작업이 CPU 집약적인 작업이라면 스레드 양보가 일어나지 않기 때문에 작업을 코루틴으로 만들더라도 4+5 = 9 초가 걸리게 됩니다. 하지만 각 작업이 I/O 작업이라면 코루틴으로 만들게 되면 스레드 양보가 일어나기 때문에 5초만 걸리는 것이 맞습니다.

 

4. 3번에 이어지는 질문인데요, 만약 3번이 맞다고 하면 IO작업의 응답이 왔을 때 콜백같은 게 적용이 되어서 Dispatcher에 새로운 작업으로 추가되는걸까요?

그러면, IO요청을 보낸 스레드와 IO응답을 처리하게 되는 스레드가 왠지 다를 수도 있을 것 같은데 맞을까요?

답변: 넵 정확합니다. 코루틴이 일시 중단될 때는 Continuation이라는 실행 정보가 저장되고 코루틴 작업이 재개될 때 이 Continuation을 사용해 작업을 복구하는 상황을 거칩니다. 이 때문에 IO 요청이 시작된 스레드와 처리하는 스레드가 다를 수 있습니다.

 

좋은 질문 남겨주셔서 감사합니다. 궁금한점이 해결되셨으면 좋을 것 같습니다!
저도 코루틴을 처음 접했을 때 정말 아릅답다고 느꼈는데요ㅎㅎ 코루틴의 세계로 오신 것을 환영하고, 이 강의에서 필요하신 모든 지식을 가져가실 수 있으시길 바라겠습니다!