Golang 정리(5)-채널(channel)

강다빈·2026년 7월 17일

golang 공부

목록 보기
9/11

채널은 데이터를 주고 받을 수 있는 통로임.
이 포스팅에서는 버퍼 없는 채널의 작동 방시에 대해 작성함.

1. 채널 = 바통터치

버퍼 없는 채널의 경우 데이터 주는 것과 데이터를 받는 것이 정확히 같은 시간에 이루어져야 함.
이 특성으로 쌍방향 무한 대기(blocking) 상태가 나타남.

  • ch <- 1 (데이터를 줄 때): 데이터를 받을 때까지 그 줄에서 무한 대기
  • result := <- ch (데이터 받을 때): 데이터를 줄 때까지 그 줄에서 무한 대기

2. 데드락 발생

  • 블로킹(blocking): 특정 작업이 끝날 때까지 잠시 멈춰서서 대기하는 '정상적인 상태'
  • 데드락(deadlock): 두 개 이상의 작업이 서로 상대방의 작업이 끝나기만을 기다리며 영원히 멈춰버리는 '에러 상태'

고루틴 없이 메인 함수 안에서 채널로 데이터를 주고 받으면 데드락 발생함.

package main

import "fmt"

func main() {
    ch := make(chan int) // 버퍼 없는 채널 생성

    ch <- 1 // [1] 데이터를 보냄 (여기서 멈춤!)
    
    result := <-ch // [2] 데이터를 받음
    fmt.Println(result)
}

[1]에서 무한 대기가 발생하고 영원히 아래 라인으로 넘어갈 수 없음. 혼자서 데이터를 주지도 받지도 못하고 영원히 멈춰있는 데드락 상태에 빠짐.

3. 고루틴 사용

위의 데드락을 해결하기 위해서 데이터는 동시에 주고 받아야 함.

package main

import "fmt"

func main() {
    ch := make(chan int)

    // 새로운 심부름꾼(고루틴) 생성
    go func() {
        ch <- 1 // 고루틴이 데이터를 보내고 대기함
    }()
    
    result := <-ch // 메인 함수는 여기서 대기하다가, 고루틴이 1을 주면 받음
    fmt.Println(result)
}

고루틴을 사용하면 데이터를 동시에 주고 받을 수 있으므로 데드락 없이 다음 작업이 진행됨.

4. 무한 블로킹

채널의 블로킹 성질을 활용하여 백그라운드 서버를 만들 때 프로그램 강제 종료를 막을 수 있음.

func main() {
    // 1. 메시지를 처리하는 백그라운드 고루틴들을 실행
    go catalogManager.MenuHandler()
    go catalogManager.SubMessage(ch)

    fmt.Println("Catalog Manager가 실행 중입니다...")

    // 2. 종료 방지용 'forever' 채널 생성
    forever := make(chan bool)

    // 3. 아무도 값을 넣어주지 않는 채널을 대기함
    <-forever 
}

채널에 아무도 데이터를 주지 않기 때문에 영원기 대기하게 되어 main 함수가 종료되지 않고 백그라운드의 고루틴들이 종료되지 않고 계속 돌아가게 됨.

이때 백그라운드에서 다른 고루틴이 실행되고 있기 때문에 데드락이 발생하지 않음.

참고: https://wikidocs.net/164596

profile
하루살이

0개의 댓글