Go 언어로 개발할 때, 단순히 고루틴을 활용하여 동시성 작업을 수행할 수 있지만, 여러 패키지들을 보면 context를 선언하고 고루틴을 관리하는 코드가 빈번히 등장하는 것을 알 수 있습니다. 이 글에서는 context 패키지가 왜 쓰이는지, 그리고 실제 코드를 통해 어떻게 활용하는지 살펴보겠습니다.
왜 context를 사용하는가?
Go 언어는 고루틴을 통해 동시성 작업을 수행합니다. 동시성 프로그램에서는 특정 작업이 시간 초과되거나 취소되어야 하는 경우가 있으며, 시스템 오류로 인해 작업을 선점해야 하는 상황도 발생할 수 있습니다. 이러한 상황을 대비해 고루틴 간에 작업의 상태를 공유하고 관리하기 위해, context 패키지가 Go 1.7 버전부터 표준 라이브러리로 제공되고 있습니다.
기존에는 완료 여부를 확인하기 위해 done 채널과 같은 방식으로 고루틴 간 통신을 했지만, context 패키지를 사용하면 동시성 관리가 보다 간편하고 일관되게 이루어질 수 있습니다.
주요 함수 소개
1. Context 생성
Background() 함수는 가장 기본이 되는 빈 Context를 생성하며, 이 Context는 취소되지 않는 최상위 부모 역할을 합니다.
ctx := context.Background()
2. Context 취소
WithCancel() 함수는 부모 Context를 받아 파생된 Context와 취소 함수(CancelFunc)를 반환합니다.
ctxWithCancel, cancelFunction := context.WithCancel(ctx)
defer cancelFunction()
doWorkContext(ctxWithCancel)
Context를 고루틴이나 중요한 작업 함수에 전달하여 Context 관리를 할 수 있습니다. 명시적으로 cancelFunction()을 호출하여 자원을 회수할 수 있습니다.
3. 타임아웃 및 데드라인 설정
WithTimeout()과 WithDeadline() 함수는 각각 상대적인 기간과 절대적인 시간을 기반으로 Context를 취소하는 데 사용됩니다.
ctxWithTimeout, cancelFunction := context.WithTimeout(ctx, 150 * time.Millisecond)
defer cancelFunction()
타임아웃과 데드라인은 설정된 시간이 지나면 자동으로 CancelFunc을 호출하여 작업을 취소하게 됩니다.
4. CancelFunc 호출 시 처리
고루틴이 작업 중 Context의 CancelFunc이 호출되면, 해당 Context와 모든 파생된 Context는 Done 채널에서 수신을 받아 종료 처리를 진행합니다.
func doWorkContext(ctx context.Context) {
select {
case <-ctx.Done():
// 종료 처리: 파일이나 DB 연결 회수 등
}
}
이러한 종료 처리를 통해 파일이나 DB 연결 자원을 회수하는 작업을 수행할 수 있습니다.
5. Context에 값 추가하기
WithValue() 함수는 key-value 쌍으로 값을 추가하여, Context를 통해 값을 전달하고 사용할 수 있습니다.
ctx := context.WithValue(context.Background(), "current_user", currentUser)
if v := ctx.Value("current_user"); v != nil {
// currentUser 사용
}
이를 통해 Context에 특정 값(예: 사용자 정보)을 추가하고 필요한 곳에서 쉽게 꺼내 사용할 수 있습니다.
Best Practice
- Context 전달: 함수를 설계할 때 Context는 첫 번째 파라미터로 전달하는 것이 관례입니다.
- 취소 및 에러 처리: Done 채널을 통해 취소 신호를 수신받고, 자원 회수와 같은 종료 처리를 진행합니다.
- 안전한 사용: 모든 파생된 Context는 안전하게 고루틴에서 사용할 수 있습니다.
Golang의 context 패키지를 제대로 활용하면 고루틴 관리가 훨씬 수월해지며, 특히 자원 회수와 종료 처리와 같은 작업을 보다 안정적이고 일관성 있게 할 수 있습니다.
'프로그래밍 일반 > Go 프로그래밍' 카테고리의 다른 글
[Go] Slice 기능 요약 (1) | 2024.04.22 |
---|---|
Go 언어 Json 태그 자동 추가/삭제 (0) | 2024.04.18 |
Go 언어의 Json Tag (0) | 2024.04.18 |
GoLand 여러개 열기 (0) | 2024.04.17 |
C++ 개발자를 위한 Go 언어 요약 정리 (1) | 2024.04.15 |