[go] go 언어에서의 race condition과 sync 패키지

병행 프로그래밍에서 race condition은 공유 자원에 대해 여러 동시 작업이 발생할 때 발생하는 문제를 의미합니다. 이는 예측할 수 없는 결과를 초래하여 프로그램의 안정성을 해칠 수 있습니다.

Go 언어는 race condition을 방지하기 위해 sync 패키지를 제공합니다. 이 패키지에는 공유 자원을 안전하게 사용할 수 있도록 하는 여러 동기화 메커니즘이 포함되어 있습니다.

WaitGroup

sync 패키지에는 WaitGroup 타입이 있습니다. 이를 사용하면 고루틴들이 모두 작업을 완료할 때까지 기다릴 수 있습니다. 다음은 WaitGroup을 사용한 예제 코드입니다.

package main

import (
	"fmt"
	"sync"
)

func worker(id int, wg *sync.WaitGroup) {
	defer wg.Done()
	fmt.Printf("Worker %d 작업 완료\n", id)
}

func main() {
	var wg sync.WaitGroup
	for i := 1; i <= 5; i++ {
		wg.Add(1)
		go worker(i, &wg)
	}
	wg.Wait()
	fmt.Println("모든 작업 완료")
}

위 코드에서 sync.WaitGroup을 사용하여 고루틴들이 작업을 완료할 때까지 기다리고, 모든 작업이 끝나면 “모든 작업 완료”를 출력합니다.

Mutex

또다른 중요한 동기화 메커니즘으로 sync 패키지는 Mutex를 제공합니다. Mutex는 공유 자원을 안전하게 사용하기 위해 사용됩니다. 다음은 Mutex를 사용한 예제 코드입니다.

package main

import (
	"fmt"
	"sync"
)

var counter int
var mu sync.Mutex

func increment() {
	mu.Lock()
	counter++
	mu.Unlock()
}

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			increment()
		}()
	}
	wg.Wait()
	fmt.Println("counter:", counter)
}

위 코드에서 sync.Mutex를 사용하여 counter 변수에 대한 접근을 보호하고 있습니다.

sync 패키지에는 이 외에도 여러 동기화 메커니즘이 제공되며, 이를 통해 안전한 병행 프로그래밍을 가능하게 할 수 있습니다.

이와 관련한 더 자세한 정보는 Go 언어 공식 문서에서 확인할 수 있습니다.