[go] race condition을 방지하기 위한 sync 패키지의 기능
Race condition은 여러 고루틴이 동시에 하나의 자원에 접근할 때 발생하는 문제입니다. sync
패키지는 이러한 상황을 방지하기 위한 도구를 제공합니다. 여기에서는 sync.Mutex
와 sync.WaitGroup
의 기능에 대해 알아보겠습니다.
sync.Mutex
sync.Mutex
는 고루틴이 공유 데이터에 안전하게 접근할 수 있도록 하는 동시성 제어 방법 중 하나입니다. 아래는 sync.Mutex
를 사용하여 공유 데이터에 안전하게 접근하는 예제입니다.
package main
import (
"fmt"
"sync"
)
var (
mu sync.Mutex
balance int
)
func deposit(amount int) {
mu.Lock()
defer mu.Unlock()
balance += amount
fmt.Printf("Deposited %d\n", amount)
}
func withdraw(amount int) {
mu.Lock()
defer mu.Unlock()
if balance >= amount {
balance -= amount
fmt.Printf("Withdrawn %d\n", amount)
} else {
fmt.Println("Insufficient balance")
}
}
func main() {
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
deposit(200)
}()
go func() {
defer wg.Done()
withdraw(100)
}()
wg.Wait()
fmt.Printf("Balance: %d\n", balance)
}
위 예제에서 sync.Mutex
를 사용하여 deposit
및 withdraw
함수에서 balance
변수에 안전하게 접근하고 있습니다.
sync.WaitGroup
sync.WaitGroup
은 고루틴이 모두 종료될 때까지 기다리는 동안 사용됩니다. 아래는 sync.WaitGroup
을 사용하여 고루틴이 모두 종료될 때까지 기다리는 예제입니다.
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second)
fmt.Printf("Worker %d done\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("All workers done")
}
위 예제에서는 sync.WaitGroup
을 사용하여 모든 고루틴이 종료되기를 기다리고 있습니다.
이처럼 sync
패키지의 sync.Mutex
와 sync.WaitGroup
을 사용하여 race condition을 방지할 수 있습니다.
이러한 도구들을 사용하면 고루틴 간의 안전한 데이터 공유 및 동기화를 보장할 수 있습니다.
더 자세한 내용은 공식 Go 문서를 참고할 수 있습니다.