코루틴 (Coroutine)

1. 코루틴이란?

  • 코루틴은 비동기 프로그래밍을 쉽게 구현할 수 있는 기술.
  • Light-Weight Thread로 불리며, 쓰레드보다 가볍게 동시성을 구현 가능.
  • 주요 목표:
    • 하드웨어 자원(CPU, 메모리) 효율적인 사용.
    • 안정적이고, 직관적인 비동기 코드 작성.
    • 운영체제의 깊은 이해 없이도 협동적 작업 처리 가능.

2. 코루틴의 주요 특징

  1. 비동기 작업 최적화:
    • 대기 시간이 발생하는 작업(예: 네트워크 요청, 파일 입출력)을 효율적으로 처리.
  2. 경량성:
    • 하나의 쓰레드에서 수백만 개의 코루틴 실행 가능.
    • 코루틴은 컨텍스트 스위칭(Context Switching) 없이 동일 쓰레드에서 작업을 교체 실행.
  3. 동시성 프로그래밍:
    • 복잡한 동시성을 직관적이고 간결하게 구현.
  4. Suspendable Functions (일시중단 함수):
    • suspend 키워드를 사용하여 일시적으로 작업을 중단하고, 다른 작업을 수행.
  5. 사용자 정의 스위칭:
    • 작업 교체 시점을 개발자가 직접 지정 가능.

3. 코루틴 빌더

코루틴 실행을 시작하는 빌더를 사용하여 다양한 방식으로 작업 수행.

  1. launch:
    • 결과값을 반환하지 않는 코루틴 빌더.
    • Job 객체를 반환하여 코루틴을 제어 가능.
    val job = GlobalScope.launch {
        delay(1000) // 1초 대기
        println("코루틴 작업 완료!")
    }
    
  2. async:
    • 결과값을 반환하는 코루틴 빌더.
    • 반환값을 Deferred 객체로 받고, await()을 호출해 결과를 반환.
    val deferred = GlobalScope.async {
        delay(1000) // 1초 대기
        "코루틴 작업 완료!"
    }
    println(deferred.await()) // 결과 출력
    
  3. runBlocking:
    • 현재 쓰레드를 차단하여 코루틴 작업이 완료될 때까지 대기.
    • 주로 테스트 코드나 코루틴을 호출하는 비코루틴 환경에서 사용.
    runBlocking {
        launch {
            delay(1000)
            println("비동기 작업 완료!")
        }
        println("runBlocking 종료")
    }
    

4. 코루틴 스코프

  1. GlobalScope:
    • 앱 전체에 걸쳐 살아있는 코루틴을 생성.
    • 앱이 실행되는 동안 코루틴 유지.
    GlobalScope.launch {
        delay(1000)
        println("GlobalScope 코루틴")
    }
    
  2. CoroutineScope:
    • 필요한 시점에 생성하고, 사용 후 정리 가능.
    • 자식 코루틴의 생명 주기를 관리.
    val scope = CoroutineScope(Dispatchers.Default)
    scope.launch {
        delay(1000)
        println("CoroutineScope 코루틴")
    }
    

5. 디스패처 (Dispatcher)

코루틴이 실행될 쓰레드를 결정.

  1. Dispatchers.Main:
    • UI와 상호작용하거나 사용자 이벤트 처리에 적합.
    • Android 개발에서 많이 사용.
  2. Dispatchers.IO:
    • 네트워크 통신, 파일 입출력 등 I/O 작업에 최적화.
  3. Dispatchers.Default:
    • CPU 집약적인 작업(데이터 처리, 복잡한 계산 등)에 적합.
  4. Dispatchers.Unconfined:
    • 제한되지 않은 디스패처. 실행 환경에 따라 동적으로 실행.

6. 쓰레드와 코루틴의 차이

  쓰레드(Thread)  코루틴(Coroutine)
경량성 무겁고, 수십 개의 쓰레드 생성 시 성능 저하. 매우 가벼움. 하나의 쓰레드에서 수백만 개의 코루틴 생성 가능.
메모리 사용 각 쓰레드는 독립적인 스택 메모리를 가짐. 코루틴은 힙 메모리를 공유하며 필요 시만 메모리 사용.
교체 방식 운영체제가 컨텍스트 스위칭을 관리. 개발자가 소스 코드에서 작업 교체 시점을 명시적으로 설정.
사용 용도 주로 동시 작업을 처리하는 저수준 구현. 동시성과 비동기 작업을 처리하는 고수준 프로그래밍.
성능 다수의 쓰레드를 실행하면 메모리와 CPU 오버헤드 증가. 효율적. CPU 자원을 최소화하며 동시성 작업 처리.
오버헤드 쓰레드 생성과 종료, 컨텍스트 스위칭 비용 큼. 오버헤드가 적고, 효율적으로 스케줄링.

7. 예시 코드

1) 간단한 코루틴 실행

fun main() = runBlocking {
    launch {
        delay(1000)
        println("첫 번째 코루틴")
    }
    println("메인 함수")
}

2) 여러 코루틴 실행

fun main() = runBlocking {
    val job1 = async {
        delay(2000)
        "작업 1 완료"
    }
    val job2 = async {
        delay(1000)
        "작업 2 완료"
    }
    println(job1.await())
    println(job2.await())
}

8. 추가 학습이 필요한 주제

  1. 코루틴 컨텍스트와 스코프:
    • CoroutineScope와 SupervisorJob의 역할 및 사용 방법.
  2. 에러 처리:
    • 코루틴 내 예외 처리 방법 (try-catch, supervisorScope).
  3. 코루틴 채널 (Channels):
    • 코루틴 간 데이터를 주고받는 통신 방식.
  4. Flow:
    • Kotlin의 비동기 데이터 스트림 처리 도구.
  5. 테스트:
    • runBlockingTest와 같은 코루틴 기반 테스트 도구 활용.

9. 결론

코루틴은 효율적인 비동기 프로그래밍동시성 처리를 위한 강력한 도구입니다. Google에서 Android 개발에 적극 권장하며, 현대적인 비동기 처리를 위해 필수적인 기술로 자리 잡고 있습니다. 학습을 통해 코루틴의 다양한 사용법과 최적화 기법을 익히는 것이 중요합니다. 😊

 

'CS ( Computer Science ) > 운영 체제 (Operating Systems)' 카테고리의 다른 글

[OS] 자원 관리  (0) 2025.02.20
[OS] 비동기 프로그래밍  (0) 2025.02.18
[OS] 쓰레드  (0) 2025.02.17
[OS] 프로세스와 쓰레드  (0) 2024.11.24

+ Recent posts