패키지 닫기, sync 사용 세부 정보

3464 단어 golang

코드


먼저 코드를 보면 다음과 같습니다.
func main() {
    var a []int
    for i := 0; i < 100; i++ {
        go func() {
            a = append(a, i)
        }()
    }
    time.Sleep(2 * time.Second)
    fmt.Println(a)
}

이 테스트 코드는 원소가 0에서 100까지의 슬라이드를 원하지만, 이 단락의 코드는 많은 문제를 숨긴다.

패킷 함수


먼저 이 코드의 실행 결과를 보십시오:
[10 12 13 13 13 13 21 24 25 28 28 28 28 28 28 29 29 29 36 38 39 39 40 41 41 41 41 41 41 45 45 45 45 46 47 48 49 50 51 52 61 61 61 61 61 61 61 61 61 61 73 73 74 74 75 76 76 77 77 77 77 77 77 77 77 77 83 85 85 88 88 89 91 92 93 93 93 93 93 93 93 93 100 100 100 100 100 100 100]

많은 요소가 같다는 것을 알 수 있다. 이것이 바로 이 코드의 첫 번째 오류이다. 패키지 함수를 사용할 때 코드에서 이런 매개 변수 i를 전달하는 방법은 깊은copy가 아니라 변수 바늘을 전달하는 것이다.이런 상황이 발생한 원인을 설명해 보세요. i , append **i** , .코드를 다음과 같이 수정합니다.
func main() {
    var a []int
    for i := 0; i < 100; i++ {
        go func(i int) {
            a = append(a, i)
        }(i)
    }
    time.Sleep(2 * time.Second)
    fmt.Println(a)
}

실행 결과는 다음과 같습니다.
[5 4 8 7 2 12 15 13 14 24 22 23 25 18 21 17 20 28 29 31 30 32 33 34 35 36 37 38 39 41 40 42 44 50 45 48 49 55 51 52 53 54 46 47 57 56 58 59 60 65 61 62 63 64 68 66 67 70 69 72 74 71 73 75 76 80 77 78 79 86 81 82 83 85 89 87 88 84 90 91 92 95 93 94 97 96 98 99]

중복원소는 없지만 원소가 부족한 것을 볼 수 있어 두 번째 문제를 일으켰다.

다중 협정의 경쟁 문제


상기 코드와 같이 여러 번 실행하면 매번 실행하는 결과에 요소가 적다는 것을 발견할 수 있다. 사실 진정한 원인은 이다.이 문제를 설명하려면 go의 수조, 슬라이드, 그리고 append 메커니즘에 대해 좀 알고 참고해야 한다.
Arrays, slices (and strings): The mechanics of 'append'
현재 우리가 성명한 슬라이드가 수조와 다르다는 것을 알고 있다. 매번 append가 있을 때마다 우리는 메모리copy와 함께 자동으로 용량을 확대하는 목적을 달성한다. A 프로토콜이 a의 메모리 데이터를 읽을 때 B 프로토콜이 쓰기 작업을 완성했다. 이때 A 프로토콜이 계속 append를 부여하면 프로토콜 B의 업데이트 결과를 잃어버린다.만약 우리가 슬라이드를 수조로 바꾼다면 이 문제는 존재하지 않을 것이다.

func main() {
    var a [100]int
    for i := 0; i < 100; i++ {
        go func(i int) {
            // a = append(a, i)
            a[i] = i
        }(i)
    }
    time.Sleep(2 * time.Second)
    fmt.Println(a)
}

결실
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]

서로 자물쇠를 밀어내거나,
func main() {
    var a []int
    var mu sync.Mutex
    for i := 0; i < 100; i++ {
        go func(i int) {
            mu.Lock()
            a = append(a, i)
            mu.Unlock()
        }(i)
    }
    time.Sleep(2 * time.Second)
    fmt.Println(a)
}

결실
[1 0 2 9 7 8 10 4 5 3 11 6 12 14 13 16 15 23 20 21 22 19 25 24 17 26 18 27 28 29 32 30 31 34 35 36 40 33 37 39 38 42 43 41 44 51 45 49 50 55 52 53 48 54 46 47 57 56 58 59 60 64 61 62 63 68 72 70 71 74 69 75 73 65 66 67 76 79 77 78 85 80 81 82 83 84 86 88 87 90 89 91 92 93 96 94 95 97 98 99]

결론

  • 클로즈업은 주의 변수 전달이 지침인지 값인지, 그리고 클로즈업 변수의 두 가지 전달 방식을 사용한다.
  • 라인 안전에 주의하세요.

  • 결어


    모두 함께 공부하고, 함께 교류하며, 함께 진보하기를 바랍니다!
    연락 주세요.
    qq:820932773
    gmail: [email protected]

    좋은 웹페이지 즐겨찾기