sync.Once: Go 동시성 문제 해결의 핵심
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
개발 툴
대상자
Go 개발자 (1~2년 경력, goroutine 및 mutex 이해 필요)
난이도: 중간 (기본 개념 이해 후 활용 팁 제공)
핵심 요약
sync.Once
는sync
패키지의Do(f func())
메서드를 통해 동시성 환경에서 특정 함수를 정확히 한 번 실행하는 도구.- 사용 사례: 싱글톤 초기화 (
global logger
), 지연 로딩 (database pool
), 중복 작업 방지 등. - 성능: 첫 번째 실행 시
Mutex
사용, 이후에는atomic.LoadUint32
로 경량한 접근 가능.
섹션별 세부 요약
1. 소개
sync.Once
는 중복 실행 방지와 자원 낭비 최소화를 위한 Go의 핵심 도구.- 사용 예시:
config 파일 로딩
,DB 연결 초기화
,싱글톤 생성
등. - 장점:
sync.Mutex
보다 간단,init()
보다 유연한 실행 시점 제어.
2. API 및 사용법
- 메서드:
func (o *Once) Do(f func())
- f
: 입력/출력 없이 실행되는 함수.
- 동작: Do
첫 호출 시 f
실행, 이후 호출 시 무시.
- 예제 코드:
```go
var once sync.Once
once.Do(func() { fmt.Println("실행됨") })
```
3. 내부 구현 원리
- 구조체:
```go
type Once struct {
done uint32 // 0: 미실행, 1: 완료
m Mutex // 첫 번째 실행 보호
}
```
- 동작 흐름:
atomic.LoadUint32
로done
확인 (0일 경우만Mutex
잠금).done
이 0일 경우f()
실행 후atomic.StoreUint32
로done
1로 업데이트.- 이후 호출은
done
체크 후 즉시 종료.
4. 성능 및 안정성
- 첫 실행:
Mutex
잠금으로 동기화 보장. - 이후 실행:
atomic.LoadUint32
로 경량한 접근. - 안정성:
atomic
과Mutex
조합으로 경쟁 조건 방지.
5. 실제 사용 사례
- 싱글톤 초기화:
```go
var config *Config
var once sync.Once
func GetConfig() *Config {
once.Do(func() { config = &Config{...} })
return config
}
```
- DB 연결 풀 생성:
```go
var db *sql.DB
func GetDB() *sql.DB {
once.Do(func() { db, _ = sql.Open(...) })
return db
}
```
결론
- 실무 팁:
sync.Once
는 초기화 작업에 최적화되어 있으며,sync.Mutex
또는init()
보다 간결하고 효율적. - 주의사항:
Do
함수 내부에서panic
발생 시, 다른 goroutine에 영향을 줄 수 있으므로 예외 처리 필수. - 핵심 원칙: "한 번만 실행"이 필요한 작업에
sync.Once
사용, 중복 작업 방지 및 자원 최적화를 목표로.