관리 메뉴

피터의 개발이야기

[Kotlin] Kotlin의 채널 소개 본문

Programming/Kotlin

[Kotlin] Kotlin의 채널 소개

기록하는 백앤드개발자 2024. 9. 19. 10:10
반응형

ㅁ 들어가며

ㅇ Kotlin의 채널은 코루틴 간에 데이터를 안전하게 전송하고 공유하기 위한 통신 기본 요소다. 채널은 동시성 프로그래밍에서 매우 유용한 도구로, 생산자-소비자 패턴을 구현하는 데 특히 적합하다.

 

ㅁ 채널의 기본 개념

ㅇ 채널은 일종의 파이프라인으로 생각할 수 있다. 개념적으로 큐와 유사하다. 한쪽 끝에서 데이터를 보내고 다른 쪽 끝에서 데이터를 받는다. 이를 통해 여러 코루틴 간의 안전한 통신이 가능해진다.

 

@Test
fun should_pass_data_from_one_coroutine_to_another() {
    runBlocking {
        // given
        val channel = Channel<String>()

        // when
        launch { // coroutine1
            channel.send("Hello World!")
        }
        val result = async { // coroutine2
            channel.receive()
        }

        // then
        assertThat(result.await()).isEqualTo("Hello World!")
    }
}

 

ㅁ 채널의 종류

ㅇ Kotlin에서는 두 가지 주요 유형의 채널을 제공한다.

  1. 버퍼 없는 채널 (Unbuffered Channel)
  2. 버퍼 있는 채널 (Buffered Channel)

ㅁ 버퍼 없는 채널

버퍼 없는 채널은 송신자와 수신자가 만날 때만 데이터 전송이 이루어진다. 이는 동기화된 통신을 제공한다.

ㅁ 버퍼 있는 채널

버퍼 있는 채널은 지정된 크기의 버퍼를 가지며, 버퍼가 가득 차기 전까지는 송신 작업이 즉시 완료된다.

ㅁ 채널 사용 예제

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*

fun main() = runBlocking {
    val channel = Channel<Int>()
    launch {
        // 데이터 송신
        for (x in 1..5) {
            channel.send(x * x)
        }
        channel.close() // 채널 닫기
    }

    // 데이터 수신
    for (y in channel) {
        println(y)
    }
    println("Done!")
}

ㅇ 이 예제에서는 1부터 5까지의 제곱값을 채널을 통해 전송하고 수신한다.

ㅁ 채널의 주요 연산

ㅇ 채널에는 몇 가지 주요 연산이 있다.

  1. send(): 채널에 데이터를 보낸다.
  2. receive(): 채널에서 데이터를 받는다.
  3. close(): 채널을 닫는다.

ㅁ 채널 사용의 장점

  1. 안전한 동시성: 채널은 여러 코루틴 간의 안전한 통신을 보장한다.
  2. 유연성: 다양한 동시성 패턴을 구현할 수 있다.
  3. 가독성: 복잡한 비동기 로직을 더 읽기 쉽게 만든다.

ㅁ 고급 채널 사용

ㅇ 채널은 더 복잡한 시나리오에서도 사용될 수 있다. 예를 들어, 팬인(fan-in)과 팬아웃(fan-out) 패턴을 구현할 수 있다:

fun CoroutineScope.produceNumbers() = produce<Int> {
    var x = 1
    while (true) {
        send(x++)
        delay(100)
    }
}

fun CoroutineScope.square(numbers: ReceiveChannel<Int>): ReceiveChannel<Int> = produce {
    for (x in numbers) {
        send(x * x)
    }
}

fun main() = runBlocking {
    val numbers = produceNumbers()
    val squares = square(numbers)
    for (i in 1..5) {
        println(squares.receive())
    }
    println("Done!")
    coroutineContext.cancelChildren()
}

ㅇ 이 예제에서는 숫자를 생성하는 프로듀서와 이를 제곱하는 프로세서를 구현했다.

ㅁ 마무리

  Kotlin의 채널은 코루틴 기반 동시성 프로그래밍에서 강력한 도구다. 채널을 통해 복잡한 동시성 패턴을 구현할 수 있으며, 코드의 가독성과 유지보수성을 높일 수 있다. 채널의 올바른 사용은 효율적이고 안전한 동시성 코드 작성에 큰 도움이 된다.

ㅁ 함께 보면 좋은 사이트

Kotlin의 채널 소개 

반응형
Comments