WaitGroups 참조의 포인터 또는 변수
동기화 패키지 내에서 WaitGroups에 대한 추가, 완료 및 대기 기능은 모두 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() }
이 코드에서 Done은 포인터 변수를 사용하여 호출되는 반면 Add 및 Wait는 변수(포인터가 아님)를 사용하여 호출됩니다.
설명:
변수 선언 var wg sync.WaitGroup에도 불구하고 Add, Done 및 Wait 함수는 포인터 수신기(*WaitGroup)를 통해 액세스됩니다. wg의 값은 Go 컴파일러에 의해 암시적으로 포인터로 변환됩니다. 이는 함수 선언에서 볼 수 있듯이 메서드가 포인터 수신기로 정의되기 때문에 필요합니다.
Add -------> func (wg *WaitGroup) Add(delta int) Done ------> func (wg *WaitGroup) Done() Wait ------> func (wg *WaitGroup) Wait()
포인터가 아닌 값을 포인터 수신기 메서드에 전달할 때 컴파일러는 자동으로 해당 주소(포인터 값). 따라서 wg가 변수로 선언되더라도 세 함수는 모두 wg에 대한 포인터에서 호출됩니다.
포인터 수신기를 사용하는 주된 이유는 불필요한 데이터 복사를 피하기 위한 것입니다. 포인터를 전달하면 함수는 복사본을 만드는 대신 기본 WaitGroup을 직접 수정할 수 있습니다. 이는 특히 자주 수정되는 WaitGroups의 성능을 향상시킵니다.
제공된 코드에서 wg의 주소를 작업자에게 전달하는 것이 중요합니다. 왜냐하면 wg가 값(& 없이)으로 전달된 경우, 각 작업자는 기본 함수의 추가 및 대기와 다른 포인터를 참조합니다. 이로 인해 잘못된 동작이 발생하게 됩니다.
위 내용은 변수로 선언된 경우에도 WaitGroup의 Add, Done 및 Wait 함수가 포인터를 사용하여 호출되는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!