5.3.1 sync.Mutex
뮤텍스는 여러 고루틴에서 공유하는 데이터를 보호해야 할 때 사용한다. 뮤텍스 구조체는 다음 함수를 제공한다
• func (m *Mutex) Lock(): 뮤텍스 잠금
• func (*Mutex) Unlock(): 뮤텍스 잠금 해제
임계 영역(critical section)의 코드를 실행하기 전에는 뮤텍스의 Lock() 메서드로 잠금을 하고, 처리 완료 후에는 Unlock() 메서드로 잠금을 해제한다.
먼저 여러 고루틴에서 뮤텍스를 사용하지 않고 공유 데이터에 접근하는 코드를 보자.
package main import ( "fmt" "runtime" ) type counter struct { i int64 } // counter 값을 1씩 증가시킴 func (c *counter) increment() { c.i += 1 } // counter 값을 출력 func (c *counter) display() { fmt.Println(c.i) } func main() { // 모든 CPU를 사용하게 함 runtime.GOMAXPROCS(runtime.NumCPU()) c := counter{i: 0} // 카운터 생성 done := make(chan struct{}) // 완료 신호 수신용 채널 // c.increment()를 실행하는 고루틴 1000개 실행 for i := 0; i < 1000; i++ { go func() { c.increment() // 카운터 값을 1 증가시킴 done <- struct{}{} // done 채널에 완료 신호 전송 }() } // 모든 고루틴이 완료될 때까지 대기 for i := 0; i < 1000; i++ { <-done } c.display() // c의 값 출력 }
실행 결과
994