코루틴이란?

  • by

콜린 소개

코루틴은 종종 백엔드 개발자들 사이에서 코틀린이 제공하는 기능과 착각하는 것이 많습니다.

하지만 자바스크립트, C#, Go 등 여러 언어로 이미 지원하는 개념이며 새로운 개념, 기술이 아닙니다.

코루틴에 대해 콜백 지옥에 대해 알아보자

콜백 지옥은 함수형 패러다임을 적용한 언어로 등장하는 형태입니다.

함수에서 최종 결과를 얻기 위해 콜백 함수를 과도하게 호출하면 콜백 지옥이 발생하여 이러한 코드를 읽기 쉽고 디버깅하기가 어렵습니다.

예를 들어 간단한 주문을 수행하는 논리를 구현한다고 가정합니다.

memberRepository.findByIdOrNull(memberId)
    .subscribe { buyer ->
        productRepository.findByIdIn(memberIds)
            .subscriber {prds ->
                orderItemService.save(prds)
                    .subscribe { items ->
                        orderRepository.createOrder(buyer, items)
                    }
                    .whenComplete { order, _ -> emitter.success(order)
            }
    }

동기로 짜낼 때보다 보기 쉽고, 어느 함수로 역할이 모두 모여 있기 때문에 메인터넌스도 어려워집니다.

코루틴?

코루틴은 이러한 콜백 지옥을 탈출하는 탈출구입니다.

또한 코루틴은 세 개의 키워드로 액세스할 수 있습니다.

  1. 연동 멀티태스킹
  2. 동시성 프로그래밍 지원
  3. 비동기 처리를 쉽게 지원

여기서 가장 주목할만한 개념은 협력적인 멀티태스킹입니다.

협력 멀티태스킹

Cooperation에 CO 태스크를 의미하는 Routine과 함께 협력하는 함수 태스크를 의미합니다.

이 코루틴을 알기 위해서는 먼저 메인 루틴과 서브 루틴을 알아야합니다.

fun main(String() args) {    // main routine
    // .. doSomething
    val a = 10
    val b - 10

    val result = plus(a, b)
}

fun plus(a: Int, b: Int) = a + b   // sub routine

위의 코드를 보면 main 함수가 main routine이고 여기서 호출됩니다.

plus 메소드가 서브루틴이 됩니다.

흐름은 종종 예상대로


sub routine는 우선 입구와 나오는 포인트가 명확합니다.

첫 번째 항목에서 return 문이나 닫는 괄호를 만나면 루틴을 빠집니다.

그리고, 엔트리시에 thread가 블록 시스템 콜인 경우, 다른 조작은 할 수 없습니다.

그럼 코루틴은 어때?


코루틴은 진입점이 복수 있으면서 함수를 빠지는 탈출점도 여러가지 있습니다.

즉, 코루틴은 자유롭게 함수를 가지고 다니는 표현이 맞습니다.

코드로 보면 다음과 같습니다.

suspend fun createMember(member: Member): MemberResponseDto {

    checkEmailDuplication(member.email)
    checkNicknameDuplication(member.nickname)

    val savedMember = memberRepository.save(member)

    return MemberResponseDto(member)
}

suspend fun checkEmailDuplication(email: String) {
   // .. doSomething
}

suspend fun checkNicknameDuplication(nickname: String) {
   // .. doSomething
}

// ... implemented something

이 코드는 코루틴으로 작동하는 코드입니다.

따라서 안데는 코드가 나오고 들어올 수 있습니다.

절차를 따르면 다음과 같습니다.

1. 스레드가 createMember 메소드를 호출하면 코루틴이 작성되고 함수가 실행됩니다.

2. 스레드는 checkEmailDuplication 함수 부분에서 다음 코드를 실행하지 않고 잠시 createMember 메서드를 이스케이프합니다.

3. 스레드가 코루틴을 탈출하더라도 우리가 조립한 다른 코드를 실행할 수 있습니다.

그리고 checkEmailDuplication 함수는 계속 실행됩니다.

이 함수는 개발자의 선택에 따라 병렬 프로그래밍으로 작동하거나 다른 스레드에서 작동할 수 있습니다.

4. 그런 다음 checkEmailDuplication 메서드가 종료되면 스레드가 다시 멈추고 다음 코드를 다시 실행합니다.

동시성 프로그래밍

함수를 중간에서 벗어나 다른 함수로 들어가고 다시 원점으로 돌아가서 정지한 부분에서 다시 시작하는 이 특성을 이용하여 동시성 프로그래밍을 할 수 있습니다.

예를 들어, 각 회원 등록 요구와 주문 생성 요구가 들어왔다고 가정하면 회원 가입 도중에 잠시 탈출하여 주문 생성에 필요한 작업을 수행하고 회원 가입 프로세스로 돌아가서 작업하는 방법을 마치 동시에 하도록 매우 빠르게 작업하는 경우 이것은 동시 프로그램과 동일한 동작입니다.

그렇다면 성능은 어떻습니까?

코루틴은 일반적인 스레드를 사용한 동시성 프로그래밍과 차원의 다른 효율성을 보여줍니다.

하나의 CPU에서 위의 예를 실행하면 두 스레드에서 전환이 이루어지고 작업이 이루어지며 이러한 스위칭은 너무 비쌉니다.

(Thread 에는 Register 나 Heap static code stack 등 많은 정보가 포함되어 있어, 그것을 저장한 후에 다른 Thread 의 Context 를 호출할 필요가 있기 (위해)때문에, 이 과정에서 비용이 발생합니다.

)

그러나 코루틴은 비동기적이고 컨텍스트 스위치 없이 작동할 수 있기 때문에 훨씬 더 나은 성능을 보여줍니다.

간결한 비동기 처리

마지막으로 코루틴의 꽃인 비동기 처리로 코드가 얼마나 간결해지는지 살펴 보겠습니다.

suspend fun createOrder(memberId: Long, productIds: List<Long>) {
	
    try {
    	val buyer = memberRepository.findByIdOrNull(memberId)
        val products = productRepository.findByIdIn(productIds)
    
        val orderItems = orderItemRepository.saveAll(OrderItems.create(products))
    
        orderRepository.save(Order.create(buyer, orderItems))
    } catch (e: Exception) {
    	log.error("error") // 예시일 뿐 실제로 이렇게 처리하는 사람은 없길 바란다.

.. } }

첫 번째 callback에서 더러운 코드가 매우 간결하게 바뀌었습니다.

물론 더 자세히 살펴보면 리포지토리의 코드도 달라지지만 크게 차이는 없습니다.

이것이 가능한 이유는, 각각의 함수를 호출할 때마다, 잠시 createOrder 메소드를 이스케이프 해, 작업이 끝나면 돌아가서 조작할 수 있기 때문입니다.

비동기화는 유지하면서 가독성을 높인 것으로 보입니다.

주의사항

이 기사를 읽고 코루틴을 무조건 써야합니다.

성능이 좋은 것에 대한 액세스를 기대하십시오. 이 문장은 비동기적이고 힘든 사람을위한 문장이며 비동기식을 사용하지 않더라도 무리하게 작성할 필요가 없습니다.

이 점은 꼭 참고하십시오.

또한 CS의 기본기인 비동기 context switching 병렬성과 동시성에 대해서는 기본적으로 숙지해 보세요.

Ref.

https://wooooooak.github.io/kotlin/2019/08/25/%EC%BD%94%ED%8B%80%EB%A6%B0-%EC%BD%94%EB%A3%A8% ED%8B%B4-%EA%B0%9C%EB%85%90-%EC%9D%B5%ED%9E%88%EA%B8%B0/

코틀린 코루틴 (coroutine)의 개념을 익히는 · 쾌락 코딩

코트린 코루틴 개념 배우기 25 Aug 2019 코루틴 연구 전에 코루틴을 이해하기 위한 두 가지 발언이 있었지만 이번에는 보다 원리적인 코루틴에 대해 배우고 싶습니다.

코루틴의 개념은 정확

wooooooak.github.io

https://kotlinlang.org/docs/coroutines-and-channels.html#blocking-requests

Coroutines and channels – tutorial | Kotlin

kotlinlang.org