ONE QUESTION AT A TIME.

천천히 생각하고, 분명하게.

TODAY’S QUESTION586 / 1500
언어·런타임난이도 하5분 답변 목표 · 보강본

여러 고루틴이 하나의 채널로 결과를 보냅니다. 수신자가 먼저 종료할 때 채널을 닫아도 되며, close는 누가 해야 하나요?

잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?

답변과 점검 포인트 펼치기답변 접기
01

구두 답변

정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.

채널을 닫는 것은 더 이상 값을 보내지 않겠다는 신호입니다. 보통 모든 송신이 끝났다는 것을 아는 쪽이 닫아야 합니다. 수신자가 더 받기 싫다고 임의로 닫으면 송신자가 여전히 값을 보내다가 패닉이 날 수 있습니다. 소비 중단과 생산 완료를 같은 신호로 취급하지 않겠습니다.

닫힘은 생산 완료의 신호

Go 채널은 고루틴 사이에서 값을 전달하는 통로입니다. close는 ‘더 이상 송신하지 않는다’는 표시이지 송신자에게 중단을 요청하는 함수가 아닙니다. 아래는 잘못된 순서를 보여 주는 설명용 코드입니다.

ch := make(chan int, 1)
close(ch)
ch <- 1 // panic: send on closed channel

수신자가 떠나는 경우에는 생산자에 취소를 알리고, 모든 송신이 끝났음을 아는 주체가 필요한 경우 채널을 닫도록 해야 합니다.

여러 생산자가 하나의 채널로 결과를 보낸다면, 각 생산자가 자기 일이 끝났다고 닫으면 안 됩니다. 저는 생산자들의 종료를 기다리는 조정자가 마지막에 닫도록 하겠습니다. 수신자는 range로 남은 값을 읽고 종료할 수 있습니다. 닫힌 채널에서 읽는 것은 가능하지만 버퍼가 비면 영값과 종료 상태를 받으므로, 일반 수신에서는 종료 여부를 확인해야 합니다.

소비 취소와 다중 생산자

반대로 수신자가 취소할 때는 별도의 context나 취소 신호를 전달하고 생산자의 송신도 그 신호를 기다릴 수 있게 만들겠습니다. 그래야 수신자가 떠난 뒤 송신에서 영원히 멈추지 않습니다. 채널을 닫아야 메모리가 해제되는 것은 아니므로, 항상 close를 넣는 습관보다는 종료를 알릴 필요가 있는지와 누가 소유하는지를 먼저 정하겠습니다. 테스트에서는 생산자 여러 개의 동시 종료와 수신자의 조기 취소를 재현해, 이중 close·송신 패닉·남은 고루틴이 없는지 확인하겠습니다.

선택 기준과 검증

수신자에게 채널을 노출할 때는 chan T가 아니라 <-chan T를 반환해 그 코드가 close를 호출하지 못하게 하겠습니다. 생산자 쪽에는 chan<- T를 넘길 수 있지만 송신 전용 타입도 채널을 닫을 수 있으므로, 이것만으로 close 소유권이 자동 강제되지는 않습니다. 조정자가 실제 채널을 소유하고 생산자 종료 뒤 한 번만 닫는 구조가 필요합니다. 조기 취소에서는 context를 별도로 전파하고 송신 대기도 취소 가능하게 만들겠습니다.

nil 채널에서의 송수신은 진행하지 않으며 select에서 해당 case를 비활성화하는 데 쓸 수 있습니다. 반면 닫힌 채널은 버퍼를 모두 비운 뒤에도 수신이 즉시 영값과 ok=false를 반환하므로 종료 여부를 무시한 반복문은 CPU를 계속 사용할 수 있습니다. nil 채널을 닫거나 이미 닫힌 채널을 다시 닫는 경우도 패닉입니다. 채널의 세 상태를 같은 '값 없음'으로 처리하지 않겠습니다.

결과 송신과 취소가 동시에 준비되면 select는 취소만 우선하지 않습니다. 취소 직후 값 하나가 더 전달돼도 되는 계약인지, 소비자가 세대를 검사해 무시해야 하는지 정해야 합니다. WaitGroup은 생산자를 시작하기 전에 참여 수를 등록하고 종료 시 Done을 호출하게 하겠습니다. 소비자가 결과를 읽지 않은 채 생산자 종료만 기다리면 생산자는 송신에서 막힐 수 있으므로, 조정자의 대기와 결과 소비도 순환 의존이 없는지 검증하겠습니다.

02

득점 포인트

이해가 드러나는 지점을 확인해 보세요.

  • close를 생산 완료 신호로 정의하고 소비 취소와 분리한다.
  • 다중 생산자의 마지막 송신을 조정자가 확인한다.
  • 송신 대기·고루틴 누수를 context와 테스트로 검증한다.
03

감점 포인트

놓치기 쉬운 조건과 오해를 짚어 보세요.

  • 수신자가 먼저 close하면 생산자가 자동으로 멈춘다고 말한다.
  • 각 생산자가 자기 종료 때 채널을 닫아 이중 close를 만든다.
  • 버퍼를 키우면 취소·고루틴 누수가 해결된다고 설명한다.
04

더 파고들 거리

하나 더 질문하며 이해의 범위를 넓혀 보세요.

득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.

원리부터 공부하고 싶다면

답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.

← 전체 질문 보기