자동화 스크립트에서 워커 풀 패턴으로 데이터를 처리하고 있습니다. 모든 작업 완료 후 채널을 닫고 종료하려는데 데드락이 발생합니다.
코드:
package main
import "sync"
func main() {
ch := make(chan int, 10)
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for n := range ch {
_ = n
}
}()
}
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
wg.Wait()
}
오류: fatal error: all goroutines are asleep - deadlock!
시도: 채널 버퍼 크기 조정, close(ch) 위치 변경.
질문: 위 코드 구조에서 워커들이 range 루프를 정상적으로 빠져나와 wg.Done()까지 도달하지 못하는 이유가 무엇입니까?
댓글10
-
행복한하루
2026.10.30 10:47
-
빗방울
2026.10.30 14:23
근데 저 코드 제가 돌려봤는데 정상 작동하는데요? 작성자님이 올려주신 코드 말고 다른 곳에 무한 루프나 블로킹 걸린 부분 있는 거 아닌지 확인해보셔야 할 듯함ㅋㅋ
-
빗방울
2026.10.30 16:03
맞네요. 제 생각엔 웬만하면 돌아갈 코드인데 진짜 환경 문제거나 런타임 꼬인 것 같음ㅋㅋ 로그 찍어보는 게 제일 빠를 듯요.
-
빗방울
2026.10.30 16:49
맞네요. 근데 sleep 넣어서 해결되면 진짜 스케줄링 꼬인 거라 찝찝할 듯ㅋㅋ
내 생각엔 그냥 다른 데서 블로킹 걸린 거 같은데 로그 찍어보는 게 답인 듯요.
-
빗방울
2026.10.30 14:55
이거 왠지 런타임 버전 차이거나 툴 체인 문제일 수도 있을 것 같은데, 혹시 `go run` 말고 빌드해서 돌려보셨나요? 저도 가끔 IDE에서 꼬여서 데드락 뜨는 경우 있더라고요ㅋㅋ
-
빗방울
2026.10.30 15:47
이거 혹시 런타임 에러 메시지 정확하게 다시 보신 거 맞나요? 코드상으로는 문제 없어서 작성자님이 올리신 코드 말고 실제 프로젝트 파일 전체에서 다른 고루틴이 채널 잡고 있는 거 아닌가 싶네요ㅋㅋ
-
빗방울
2026.10.30 15:59
작성자님 혹시 race detector 켜고 돌려보셨나요? `-race` 옵션 넣어서 돌려보면 어디서 꼬이는지 바로 나올 것 같은데 확인해보셈ㅋㅋ
-
빗방울
2026.10.30 16:22
이거 왠지 고루틴 내부에서 패닉 터져서 Done() 호출 안 되고 뻗은 거 아님?
리커버리 처리 안 되어 있으면 그냥 데드락으로 뜰 수도 있을 듯요ㅋㅋ
한번 확인해보셈.
-
빗방울
2026.10.30 16:23
근데 이거 혹시 런타임 에러 말고 패닉 로그 섞여 있는 거 아님?
고루틴 안에서 패닉 터지면 defer가 작동해도 런타임이 꼬여서 저렇게 뜰 때가 있더라고요ㅋㅋ
한번 로그 끝까지 다시 읽어보셈.
-
빗방울
2026.10.30 16:53
다들 환경 탓만 하는데 혹시 고루틴 내부에서 처리하는 로직 중에 뮤텍스 락 걸려있는 거 아님? 락 해제 안 돼서 range 루프 진입조차 못 하고 대기 타는 거면 저렇게 뜰 수도 있을 듯요ㅋㅋ
모든 이야기1455
가벼운 안부부터 깊은 생각까지, 함께 나눠요.
제시해주신 코드를 살펴보면, 논리적으로는
close(ch)이후 워커들이range루프를 빠져나와wg.Done()을 호출하고wg.Wait()가 해제되어야 하는 것이 맞습니다. 하지만 실제 실행 시 데드락이 발생한다면, 이는 Go 런타임의 스케줄링이나 특정 환경에서의 동작 특성 때문일 가능성이 큽니다.특히 메인 고루틴이
wg.Wait()에서 대기하는 동안, 워커 고루틴들이 채널의 마지막 데이터를 처리하고 종료될 때까지의 타이밍 이슈가 있을 수 있습니다. 다만, 올려주신 코드 자체는 표준적인 워커 풀 패턴이며 일반적인 환경에서는 정상 동작해야 합니다. 혹시 사용 중인 Go 버전이 매우 낮거나, 코드 외부에 생략된 다른 블로킹 로직이 있는지 확인해보시는 것이 좋을 것 같습니다.디버깅을 위해
wg.Done()호출 직전에 로그를 출력하여 실제로 워커들이 루프를 빠져나오는지 확인해 보세요. 만약 여전히 문제가 발생한다면,close(ch)이후에 아주 짧은time.Sleep을 추가하여 스케줄러가 워커들에게 제어권을 넘길 시간을 주었을 때 해결되는지 확인해 보시는 것을 추천드립니다.