동시 Go 루틴의 데이터 경합
이 코드는 동시 Go 루틴의 데이터 경합 문제를 보여줍니다. 루틴:
package main import ( "fmt" "time" ) type field struct { name string } func (p *field) print() { fmt.Println(p.name) } func main() { data := []field{{"one"}, {"two"}, {"three"}} for _, v := range data { go v.print() } <-time.After(1 * time.Second) }
문제:
코드는 임의의 루틴에 "one", "two" 및 "3"을 인쇄하는 대신 "3"을 세 번 인쇄합니다. 주문하다. 이는 데이터 경쟁이 있기 때문입니다.
설명:
암시적으로 코드는 고루틴 함수에 대한 인수를 평가할 때 변수 v의 주소를 사용합니다. 고루틴 함수 v.print()는 (&v).print()와 동일합니다. 루프는 v의 값을 변경하고, 고루틴이 실행될 때 루프의 마지막 값("3")을 갖게 됩니다.
수정 사항:
이 데이터 경합을 해결하는 방법에는 여러 가지가 있습니다.
for _, v := range data { v := v // short variable declaration of new variable `v`. go v.print() }
data := []*field{{"one"}, {"two"}, {"three"}} // note '*' for _, v := range data { go v.print() }
data := []field{{"one"}, {"two"}, {"three"}} // note '*' for i := range data { v := &data[i] go v.print() }
for _, v := range data { go func(v field) { v.print() // take address of argument v, not range variable v. }(v) }
위 내용은 Go에서 고루틴을 시작할 때 데이터 경합을 피하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!