Go concurrency distilled
Go 동시성 한눈에 정리하기
Go 동시성의 주요 개념을 실행 가능한 예제로 정리한 미니북입니다. 고루틴과 채널부터 동기화, 테스트, 스케줄링, 진단 도구까지 빠르게 훑으며, 데이터 경쟁과 경쟁 조건의 차이도 설명합니다.
- 주제
AI 요약
Go 동시성 주제를 짧게 복습할 수 있도록 만든 미니북입니다. 각 항목에 코드를 직접 바꿔 실행하는 인터랙티브 예제를 붙였고, 정적 예제를 담은 PDF도 제공합니다. 입문자를 위한 단계별 안내서라기보다 이미 Go를 아는 개발자를 위한 빠른 참고 자료입니다.
고루틴과 채널
고루틴(goroutine)은 go 키워드로 시작하는 함수 실행 단위입니다. Go 런타임은 여러 고루틴을 운영체제 스레드에 배치하며, 고루틴은 스레드보다 가벼워 수천 개까지 실행할 수 있습니다. sync.WaitGroup은 작업 수를 세고 모든 고루틴이 끝날 때까지 기다립니다. 본문은 WaitGroup.Go도 소개합니다.
채널(channel)은 고루틴 사이에서 값을 주고받는 통로입니다. 버퍼가 없는 채널은 송신과 수신이 만날 때까지 양쪽을 멈추고, 버퍼가 있는 채널은 정해진 크기 안에서 값을 보관합니다. 채널을 닫으면 더 보낼 값이 없다는 사실을 수신자에게 알립니다. 송신 전용·수신 전용 채널로 함수의 역할을 제한하는 방법과, select로 여러 채널을 기다리거나 취소 신호를 처리하는 방법도 예제로 다룹니다.
파이프라인과 작업 취소
파이프라인은 입력을 읽고, 여러 단계에서 변환한 뒤, 결과를 기록하는 구조입니다. 각 단계는 채널로 이어집니다. 결과 채널을 닫아 작업 종료를 알리거나, 완료 채널로 반환값 없는 작업의 종료를 전달할 수 있습니다. 취소 채널이나 context.Context를 사용하면 호출자가 작업을 중단할 수 있습니다. 오류 처리 방식으로는 첫 오류에서 중단하기, 결과와 오류를 하나의 구조체로 보내기, 오류 채널을 따로 두기 등 세 가지를 제시합니다.
시간과 동기화
time.After는 제한 시간, Timer는 한 번 실행할 작업, Ticker는 주기 작업에 씁니다. 반복문에서 타이머를 계속 새로 만들기보다 하나를 재설정하는 방법도 설명합니다. context는 취소, 타임아웃, 마감 시각을 전달하며, 자식 컨텍스트는 부모보다 긴 제한 시간을 설정할 수 없습니다. 값 전달 용도로 context.WithValue를 쓰기보다 명시적인 매개변수나 구조체를 권합니다.
WaitGroup 외에도 뮤텍스(mutex), 읽기·쓰기 뮤텍스, 세마포어, 조건 변수(sync.Cond), sync.Once, 객체 풀(sync.Pool), 원자 연산(sync/atomic)을 다룹니다. 버퍼 채널로 세마포어를 구현해 동시 작업 수를 제한하는 예제가 있습니다. 원자 연산은 개별 연산만 원자성을 보장하며, 여러 연산을 묶은 작업까지 보호하지는 않습니다. 복합 상태를 안전하게 바꾸려면 뮤텍스가 필요할 수 있습니다.
경쟁 문제와 테스트
데이터 경쟁(data race)은 여러 고루틴이 공유 데이터에 접근하고 그중 하나가 값을 바꿀 때 발생합니다. Go의 -race 옵션으로 감지할 수 있습니다. 반면 경쟁 조건(race condition)은 실행 순서에 따라 프로그램 상태가 잘못되는 문제입니다. 각각의 접근이 데이터 경쟁을 일으키지 않더라도 복합 작업의 순서가 잘못되면 발생하므로, 레이스 감지기가 모든 경쟁 조건을 찾아내지는 못합니다.
동시성 테스트에서는 채널이나 완료 신호를 동기화 수단으로 활용할 수 있습니다. 글은 synctest 패키지의 가상 시계와 synctest.Wait도 설명합니다. 이를 이용하면 고루틴이 종료되거나 안정적으로 대기하는 시점을 확인하고, 시간 초과가 포함된 테스트를 실제로 기다리지 않고 실행할 수 있습니다. 단, 뮤텍스나 입출력, 시스템 호출 대기는 이 격리 환경에서 안정적인 대기로 취급하지 않습니다.
스케줄링과 진단
실행 구조를 CPU 코어, 운영체제 스레드, Go 고루틴의 세 층으로 나눠 설명합니다. Go 런타임 스케줄러는 다수의 고루틴을 제한된 스레드에 배정하고, 채널 대기나 시스템 호출로 작업이 막히면 다른 작업을 실행합니다. 병목을 찾을 때는 런타임 지표, CPU·힙·고루틴·블록·뮤텍스 프로파일, 실행 추적(trace)을 활용합니다. net/http/pprof와 go tool pprof, go tool trace 사용법도 안내하며, 문제가 생기기 직전의 추적 정보를 보관하는 비행 기록(flight recording) 기능을 소개합니다.
원문: antonz.org / 번역·요약: Trawling