>백엔드 개발 >Golang >Go에서 슬라이스를 사용함에도 불구하고 내 고루틴이 모두 동일한 값을 인쇄하는 이유는 무엇입니까?

Go에서 슬라이스를 사용함에도 불구하고 내 고루틴이 모두 동일한 값을 인쇄하는 이유는 무엇입니까?

Susan Sarandon
Susan Sarandon원래의
2024-12-20 02:40:10808검색

Why Do My Goroutines All Print the Same Value Despite Using a Slice in Go?

데이터 레이스에서 고루틴의 동작 이해

제공된 코드 조각은 Go의 전형적인 데이터 레이스 문제를 보여줍니다. 목표는 필드 목록에서 다른 값("1", "2", "3")을 인쇄하는 것이지만 실제 결과는 "3"이 세 번 인쇄되는 것입니다.

이 문제를 해결하려면 문제를 해결하려면 데이터 경쟁이 왜, 어디서 발생하는지 이해해야 합니다.

데이터 경쟁 식별

문제는 고루틴 함수의 인수 평가. 루프가 데이터 조각을 반복할 때 범위 변수 v가 ​​루프 본문에 할당되고 v.print() 호출에 사용됩니다. 그러나 v 변수는 요소의 복사본이며 반복 중에 슬라이스가 변경되므로 고루틴은 결국 모두 슬라이스의 동일한 마지막 요소를 가리킵니다.

이는 고루틴이 실행될 때, 모두 우리가 의도한 고유 값("one", "two", " three") 대신 마지막 값("3")을 인쇄합니다.

가능 솔루션

이 문제를 해결하고 데이터 경합을 제거하는 방법에는 여러 가지가 있습니다.

  1. 루프 내부에 새 변수 만들기:

    • v := v 구문을 사용하여 루프 내에서 새 변수 v를 선언함으로써 다음을 보장합니다. 각 고루틴은 자체 데이터 복사본에서 작동합니다.
  2. 포인터 슬라이스 사용:

    • 전달하는 대신 원본 슬라이스인 경우 포인터 슬라이스(예: []*필드)를 사용할 수 있습니다. 고루틴에 전달되면 각 포인터는 데이터 경합을 피하면서 슬라이스의 고유한 요소를 가리킵니다.
  3. 슬라이스 요소의 주소 전달:

    • 또는 다음을 사용하여 각 슬라이스 요소의 주소를 고루틴에 명시적으로 전달할 수 있습니다. 구문 &데이터[i]. 이렇게 하면 각 고루틴이 의도한 요소에 대한 고유한 포인터를 갖게 됩니다.
  4. 인수와 함께 익명 함수 사용:

    • 고루틴 함수가 익명 함수 내에 있는 경우 범위 변수를 익명 함수에 대한 인수로 전달하여 격리할 수 있습니다. 데이터에 대한 goroutine의 액세스.

이러한 솔루션 중 하나를 적용하면 데이터 경합을 제거하고 goroutine이 의도한 고유 값("one", "둘", "셋") 순서에 상관없이

위 내용은 Go에서 슬라이스를 사용함에도 불구하고 내 고루틴이 모두 동일한 값을 인쇄하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.