> 백엔드 개발 > Golang > Go에서 고루틴을 시작할 때 데이터 경합을 피하는 방법은 무엇입니까?

Go에서 고루틴을 시작할 때 데이터 경합을 피하는 방법은 무엇입니까?

Mary-Kate Olsen
풀어 주다: 2024-12-08 17:37:11
원래의
234명이 탐색했습니다.

How to Avoid Data Races When Launching Goroutines in Go?

동시 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿