Counter
를 정의 (define) 한다.Inc
호출에서 증가시키면 된다.Counter
에 대해 더 많은 테스트를 작성할 예정이므로 assertCount
라는 작은 assertion (확인) 함수를 작성하여 테스트가 좀 더 명확해질 수 있도록 작성한다.wantedCount
값 만큼 반복문을 실행하며, counter.Inc()
라는 고루틴 (goroutine) 을 실행 할 것이다.WaitGroup은 관련 고루틴들이 완료되기를 기다립니다. 메인 고루틴은 기다려야할 고루틴의 숫자를 설정하기 위하여 Add를 호출합니다. 이후 각각의 고루틴들은 실행후 완료되었음을 알리기 위해 Done을 호출합니다. 이와 동시에 모든 고루틴이 완료 될때까지 Wait을 사용하여 차단 (block) 할 수 있습니다.
wg.Wait()
를 사용하여 모든 고루틴들이 Counter
에 대해 Inc
를 시도하였음을 assertion 하기 전에 분명히 할 수 있다.Mutex는 상호 배제 잠금으로 0 은 잠금 해제 된 상태를 의미합니다.
Inc
를 호출하는 첫 번째 고루틴이 Counter
에 대한 락을 획득함을 의미한다. 다른 고루틴들은 접근 권한을 얻기 위해서 해당 락이 'Unlock' 될 때까지 기다려야 한다.sync.Mutex
is embedded into the struct.Lock
과 Unlock
의 노출은 이와 관련된 메서드들을 호출하기 시작하는 순간 해당 소프트웨어에 최선의 경우 혼란을, 최악의 경우 잠재적으로 굉장히 해로울 수 있다.go vet
을 호출하면 다음과 같은 오류를 확인할 수 있다.Mutex (상호배제)는 처음 사용된 후 복사되어서는 안 됩니다.
Counter
를 값으로 assertCounter
함수에 전달하기에 해당 mutex의 복사본을 생성하게 된다.Counter
를 값이아닌 포인터로 전달 할 수 있도록 assertCounter
의 서명 (signature) 을 다음과 같이 변경한다.* Counter
가 아닌 Counter
를 전달하려고 하기 때문에 테스트가 더 이상 컴파일되지 않는다. 이를 해결하기 위해 API 유저에게 유형을 직접 초기화하지 않는 것이 더 낫다는 것을 보여주는 생성자를 만드는 것을 (개인적으로) 선호한다.Counter
를 초기화 할때 해당 함수를 테스트에서 사용한다.Mutex
를 사용하여 데이터에 잠금을 추가 할 수 있다. -Waitgroup
은 고루틴이 작업을 완료하기를 기다리는 수다.Go 초보자의 일반적인 실수는 단지 가능하거나 재미있다는 이유로 채널과 고루틴을 과도하게 사용하는 것이다. 해당 문제에 가장 적합하다는 판단이 들 때 sync.Mutex를 사용하는 것을 두려워하지 말아야 한다. Go는 문제를 가장 잘 해결하는 도구를 사용하고 한 가지 스타일의 코드를 강요하지 않도록 하는 데에 있어서 실용적이기 때문이다.
go vet
은 당신의 코드에 존재하는 미묘한 버그들에 대해 주의를 줄 수 있으니 유저들이 당신의 코드로 고통받지 않도록 빌드 스크립트에 사용하는 것을 잊지 말아야 한다.